Repository: quarkiverse/quarkus-jdiameter Branch: main Commit: 9be0f1bad518 Files: 835 Total size: 7.0 MB Directory structure: gitextract_ummft7m9/ ├── .github/ │ ├── CODEOWNERS │ ├── dependabot.yml │ ├── project.yml │ └── workflows/ │ ├── build.yml │ ├── deploy-snapshots.yml.disabled │ ├── pre-release.yml │ ├── quarkus-snapshot.yaml │ ├── release-perform.yml │ ├── release-prepare.yml │ └── release.yml.disabled ├── .gitignore ├── LICENSE ├── README.md ├── core/ │ ├── docs/ │ │ └── sources-asciidoc/ │ │ └── src/ │ │ └── main/ │ │ └── asciidoc/ │ │ ├── Chapter-Introduction.adoc~ │ │ ├── Chapter-JDiameter.adoc~ │ │ ├── Chapter-MUX.adoc~ │ │ ├── Diameter_User_Guide.adoc~ │ │ ├── Section-Introduction-Message_Format.adoc~ │ │ ├── Section-JDiameter-Configuration.adoc~ │ │ ├── Section-JDiameter-Setup.adoc~ │ │ ├── Section-JDiameter-Source_Overview.adoc~ │ │ ├── Section-JDiameter-Validator-Configuration.adoc~ │ │ ├── Section-JDiameter-Validator-Source_Overview.adoc~ │ │ ├── Section-JDiameter-Validator.adoc~ │ │ ├── Section-MUX-Setup.adoc~ │ │ ├── Section-MUX-Source_Overview.adoc~ │ │ ├── js/ │ │ │ └── default.js~ │ │ └── stylesheets/ │ │ └── telestax.css~ │ ├── jdiameter/ │ │ ├── api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── jdiameter/ │ │ │ └── api/ │ │ │ ├── Answer.java │ │ │ ├── ApplicationAlreadyUseException.java │ │ │ ├── ApplicationId.java │ │ │ ├── Avp.java │ │ │ ├── AvpDataException.java │ │ │ ├── AvpSet.java │ │ │ ├── BaseSession.java │ │ │ ├── Configuration.java │ │ │ ├── ConfigurationListener.java │ │ │ ├── DisconnectCause.java │ │ │ ├── EventListener.java │ │ │ ├── IllegalDiameterStateException.java │ │ │ ├── InternalException.java │ │ │ ├── LocalAction.java │ │ │ ├── Message.java │ │ │ ├── MetaData.java │ │ │ ├── Mode.java │ │ │ ├── MutableConfiguration.java │ │ │ ├── MutablePeerTable.java │ │ │ ├── Network.java │ │ │ ├── NetworkReqListener.java │ │ │ ├── OverloadException.java │ │ │ ├── OverloadListener.java │ │ │ ├── OverloadManager.java │ │ │ ├── Peer.java │ │ │ ├── PeerState.java │ │ │ ├── PeerStateListener.java │ │ │ ├── PeerTable.java │ │ │ ├── PeerTableListener.java │ │ │ ├── RawSession.java │ │ │ ├── Realm.java │ │ │ ├── RealmTable.java │ │ │ ├── Request.java │ │ │ ├── ResultCode.java │ │ │ ├── RouteException.java │ │ │ ├── Selector.java │ │ │ ├── Session.java │ │ │ ├── SessionFactory.java │ │ │ ├── Stack.java │ │ │ ├── StackManager.java │ │ │ ├── StackType.java │ │ │ ├── Statistic.java │ │ │ ├── StatisticRecord.java │ │ │ ├── URI.java │ │ │ ├── Wrapper.java │ │ │ ├── acc/ │ │ │ │ ├── ClientAccSession.java │ │ │ │ ├── ClientAccSessionListener.java │ │ │ │ ├── ServerAccSession.java │ │ │ │ ├── ServerAccSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── AccountAnswer.java │ │ │ │ └── AccountRequest.java │ │ │ ├── annotation/ │ │ │ │ ├── AvpDscr.java │ │ │ │ ├── AvpFlag.java │ │ │ │ ├── AvpType.java │ │ │ │ ├── Child.java │ │ │ │ ├── CommandDscr.java │ │ │ │ ├── CommandFlag.java │ │ │ │ ├── Getter.java │ │ │ │ └── Setter.java │ │ │ ├── app/ │ │ │ │ ├── AppAnswerEvent.java │ │ │ │ ├── AppEvent.java │ │ │ │ ├── AppRequestEvent.java │ │ │ │ ├── AppSession.java │ │ │ │ ├── State.java │ │ │ │ ├── StateChangeListener.java │ │ │ │ ├── StateEvent.java │ │ │ │ └── StateMachine.java │ │ │ ├── auth/ │ │ │ │ ├── ClientAuthSession.java │ │ │ │ ├── ClientAuthSessionListener.java │ │ │ │ ├── ServerAuthSession.java │ │ │ │ ├── ServerAuthSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── AbortSessionAnswer.java │ │ │ │ ├── AbortSessionRequest.java │ │ │ │ ├── ReAuthAnswer.java │ │ │ │ ├── ReAuthRequest.java │ │ │ │ ├── SessionTermAnswer.java │ │ │ │ └── SessionTermRequest.java │ │ │ ├── cca/ │ │ │ │ ├── CCASession.java │ │ │ │ ├── ClientCCASession.java │ │ │ │ ├── ClientCCASessionListener.java │ │ │ │ ├── ServerCCASession.java │ │ │ │ ├── ServerCCASessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── JCreditControlAnswer.java │ │ │ │ └── JCreditControlRequest.java │ │ │ ├── cxdx/ │ │ │ │ ├── ClientCxDxSession.java │ │ │ │ ├── ClientCxDxSessionListener.java │ │ │ │ ├── ServerCxDxSession.java │ │ │ │ ├── ServerCxDxSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── JLocationInfoAnswer.java │ │ │ │ ├── JLocationInfoRequest.java │ │ │ │ ├── JMultimediaAuthAnswer.java │ │ │ │ ├── JMultimediaAuthRequest.java │ │ │ │ ├── JPushProfileAnswer.java │ │ │ │ ├── JPushProfileRequest.java │ │ │ │ ├── JRegistrationTerminationAnswer.java │ │ │ │ ├── JRegistrationTerminationRequest.java │ │ │ │ ├── JServerAssignmentAnswer.java │ │ │ │ ├── JServerAssignmentRequest.java │ │ │ │ ├── JUserAuthorizationAnswer.java │ │ │ │ └── JUserAuthorizationRequest.java │ │ │ ├── gq/ │ │ │ │ ├── ClientGqSessionListener.java │ │ │ │ ├── GqClientSession.java │ │ │ │ ├── GqServerSession.java │ │ │ │ └── ServerGqSessionListener.java │ │ │ ├── gx/ │ │ │ │ ├── ClientGxSession.java │ │ │ │ ├── ClientGxSessionListener.java │ │ │ │ ├── ServerGxSession.java │ │ │ │ ├── ServerGxSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── GxCreditControlAnswer.java │ │ │ │ ├── GxCreditControlRequest.java │ │ │ │ ├── GxReAuthAnswer.java │ │ │ │ └── GxReAuthRequest.java │ │ │ ├── rf/ │ │ │ │ ├── ClientRfSession.java │ │ │ │ ├── ClientRfSessionListener.java │ │ │ │ ├── ServerRfSession.java │ │ │ │ ├── ServerRfSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── RfAccountingAnswer.java │ │ │ │ └── RfAccountingRequest.java │ │ │ ├── ro/ │ │ │ │ ├── ClientRoSession.java │ │ │ │ ├── ClientRoSessionListener.java │ │ │ │ ├── ServerRoSession.java │ │ │ │ ├── ServerRoSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── RoCreditControlAnswer.java │ │ │ │ └── RoCreditControlRequest.java │ │ │ ├── rx/ │ │ │ │ ├── ClientRxSession.java │ │ │ │ ├── ClientRxSessionListener.java │ │ │ │ ├── ServerRxSession.java │ │ │ │ ├── ServerRxSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── RxAAAnswer.java │ │ │ │ ├── RxAARequest.java │ │ │ │ ├── RxAbortSessionAnswer.java │ │ │ │ ├── RxAbortSessionRequest.java │ │ │ │ ├── RxReAuthAnswer.java │ │ │ │ ├── RxReAuthRequest.java │ │ │ │ ├── RxSessionTermAnswer.java │ │ │ │ └── RxSessionTermRequest.java │ │ │ ├── s13/ │ │ │ │ ├── ClientS13Session.java │ │ │ │ ├── ClientS13SessionListener.java │ │ │ │ ├── ServerS13Session.java │ │ │ │ ├── ServerS13SessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── JMEIdentityCheckAnswer.java │ │ │ │ └── JMEIdentityCheckRequest.java │ │ │ ├── s6a/ │ │ │ │ ├── ClientS6aSession.java │ │ │ │ ├── ClientS6aSessionListener.java │ │ │ │ ├── ServerS6aSession.java │ │ │ │ ├── ServerS6aSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── JAuthenticationInformationAnswer.java │ │ │ │ ├── JAuthenticationInformationRequest.java │ │ │ │ ├── JCancelLocationAnswer.java │ │ │ │ ├── JCancelLocationRequest.java │ │ │ │ ├── JDeleteSubscriberDataAnswer.java │ │ │ │ ├── JDeleteSubscriberDataRequest.java │ │ │ │ ├── JInsertSubscriberDataAnswer.java │ │ │ │ ├── JInsertSubscriberDataRequest.java │ │ │ │ ├── JNotifyAnswer.java │ │ │ │ ├── JNotifyRequest.java │ │ │ │ ├── JPurgeUEAnswer.java │ │ │ │ ├── JPurgeUERequest.java │ │ │ │ ├── JResetAnswer.java │ │ │ │ ├── JResetRequest.java │ │ │ │ ├── JUpdateLocationAnswer.java │ │ │ │ └── JUpdateLocationRequest.java │ │ │ ├── sh/ │ │ │ │ ├── ClientShSession.java │ │ │ │ ├── ClientShSessionListener.java │ │ │ │ ├── ServerShSession.java │ │ │ │ ├── ServerShSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── ProfileUpdateAnswer.java │ │ │ │ ├── ProfileUpdateRequest.java │ │ │ │ ├── PushNotificationAnswer.java │ │ │ │ ├── PushNotificationRequest.java │ │ │ │ ├── SubscribeNotificationsAnswer.java │ │ │ │ ├── SubscribeNotificationsRequest.java │ │ │ │ ├── UserDataAnswer.java │ │ │ │ └── UserDataRequest.java │ │ │ ├── slg/ │ │ │ │ ├── ClientSLgSession.java │ │ │ │ ├── ClientSLgSessionListener.java │ │ │ │ ├── ServerSLgSession.java │ │ │ │ ├── ServerSLgSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── LocationReportAnswer.java │ │ │ │ ├── LocationReportRequest.java │ │ │ │ ├── ProvideLocationAnswer.java │ │ │ │ └── ProvideLocationRequest.java │ │ │ ├── slh/ │ │ │ │ ├── ClientSLhSession.java │ │ │ │ ├── ClientSLhSessionListener.java │ │ │ │ ├── ServerSLhSession.java │ │ │ │ ├── ServerSLhSessionListener.java │ │ │ │ └── events/ │ │ │ │ ├── LCSRoutingInfoAnswer.java │ │ │ │ └── LCSRoutingInfoRequest.java │ │ │ └── validation/ │ │ │ ├── AvpNotAllowedException.java │ │ │ ├── AvpRepresentation.java │ │ │ ├── Dictionary.java │ │ │ ├── MessageRepresentation.java │ │ │ └── ValidatorLevel.java │ │ ├── impl/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── jdiameter/ │ │ │ │ │ ├── client/ │ │ │ │ │ │ ├── api/ │ │ │ │ │ │ │ ├── IAnswer.java │ │ │ │ │ │ │ ├── IAssembler.java │ │ │ │ │ │ │ ├── IContainer.java │ │ │ │ │ │ │ ├── IEventListener.java │ │ │ │ │ │ │ ├── IMessage.java │ │ │ │ │ │ │ ├── IMetaData.java │ │ │ │ │ │ │ ├── IRequest.java │ │ │ │ │ │ │ ├── ISession.java │ │ │ │ │ │ │ ├── ISessionFactory.java │ │ │ │ │ │ │ ├── StackState.java │ │ │ │ │ │ │ ├── annotation/ │ │ │ │ │ │ │ │ ├── IRecoder.java │ │ │ │ │ │ │ │ └── RecoderException.java │ │ │ │ │ │ │ ├── controller/ │ │ │ │ │ │ │ │ ├── IPeer.java │ │ │ │ │ │ │ │ ├── IPeerTable.java │ │ │ │ │ │ │ │ ├── IRealm.java │ │ │ │ │ │ │ │ └── IRealmTable.java │ │ │ │ │ │ │ ├── fsm/ │ │ │ │ │ │ │ │ ├── EventTypes.java │ │ │ │ │ │ │ │ ├── ExecutorFactory.java │ │ │ │ │ │ │ │ ├── FsmEvent.java │ │ │ │ │ │ │ │ ├── IContext.java │ │ │ │ │ │ │ │ ├── IFsmFactory.java │ │ │ │ │ │ │ │ └── IStateMachine.java │ │ │ │ │ │ │ ├── io/ │ │ │ │ │ │ │ │ ├── IConnection.java │ │ │ │ │ │ │ │ ├── IConnectionListener.java │ │ │ │ │ │ │ │ ├── ITransportLayerFactory.java │ │ │ │ │ │ │ │ ├── NotInitializedException.java │ │ │ │ │ │ │ │ ├── TransportError.java │ │ │ │ │ │ │ │ └── TransportException.java │ │ │ │ │ │ │ ├── parser/ │ │ │ │ │ │ │ │ ├── IElementParser.java │ │ │ │ │ │ │ │ ├── IMessageParser.java │ │ │ │ │ │ │ │ └── ParseException.java │ │ │ │ │ │ │ └── router/ │ │ │ │ │ │ │ └── IRouter.java │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── AbstractStateChangeListener.java │ │ │ │ │ │ ├── BaseSessionImpl.java │ │ │ │ │ │ ├── DictionarySingleton.java │ │ │ │ │ │ ├── MessageUtility.java │ │ │ │ │ │ ├── MetaDataImpl.java │ │ │ │ │ │ ├── RawSessionImpl.java │ │ │ │ │ │ ├── SessionFactoryImpl.java │ │ │ │ │ │ ├── SessionImpl.java │ │ │ │ │ │ ├── StackImpl.java │ │ │ │ │ │ ├── StackImplMBean.java │ │ │ │ │ │ ├── VersionProperties.java │ │ │ │ │ │ ├── annotation/ │ │ │ │ │ │ │ ├── Recoder.java │ │ │ │ │ │ │ ├── UnknownAvp.java │ │ │ │ │ │ │ ├── Value.java │ │ │ │ │ │ │ └── internal/ │ │ │ │ │ │ │ ├── ClassInfo.java │ │ │ │ │ │ │ ├── ConstructorInfo.java │ │ │ │ │ │ │ ├── MethodInfo.java │ │ │ │ │ │ │ └── Storage.java │ │ │ │ │ │ ├── app/ │ │ │ │ │ │ │ ├── acc/ │ │ │ │ │ │ │ │ ├── ClientAccSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── ClientAccSessionImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ └── IClientAccSessionData.java │ │ │ │ │ │ │ ├── auth/ │ │ │ │ │ │ │ │ ├── ClientAuthSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── ClientAuthSessionImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ └── IClientAuthSessionData.java │ │ │ │ │ │ │ ├── cca/ │ │ │ │ │ │ │ │ ├── ClientCCASessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── ClientCCASessionImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ └── IClientCCASessionData.java │ │ │ │ │ │ │ ├── cxdx/ │ │ │ │ │ │ │ │ ├── ClientCxDxSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── CxDxClientSessionImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ └── IClientCxDxSessionData.java │ │ │ │ │ │ │ ├── gq/ │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ └── GqClientSessionImpl.java │ │ │ │ │ │ │ ├── gx/ │ │ │ │ │ │ │ │ ├── ClientGxSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── ClientGxSessionImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ └── IClientGxSessionData.java │ │ │ │ │ │ │ ├── rf/ │ │ │ │ │ │ │ │ ├── ClientRfSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── ClientRfSessionImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ └── IClientRfSessionData.java │ │ │ │ │ │ │ ├── ro/ │ │ │ │ │ │ │ │ ├── ClientRoSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── ClientRoSessionImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ └── IClientRoSessionData.java │ │ │ │ │ │ │ ├── rx/ │ │ │ │ │ │ │ │ ├── ClientRxSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── ClientRxSessionImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ └── IClientRxSessionData.java │ │ │ │ │ │ │ ├── s13/ │ │ │ │ │ │ │ │ ├── ClientS13SessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ ├── IClientS13SessionData.java │ │ │ │ │ │ │ │ └── S13ClientSessionImpl.java │ │ │ │ │ │ │ ├── s6a/ │ │ │ │ │ │ │ │ ├── ClientS6aSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ ├── IClientS6aSessionData.java │ │ │ │ │ │ │ │ └── S6aClientSessionImpl.java │ │ │ │ │ │ │ ├── sh/ │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ ├── IShClientSessionData.java │ │ │ │ │ │ │ │ ├── ShClientSessionDataLocalImpl.java │ │ │ │ │ │ │ │ └── ShClientSessionImpl.java │ │ │ │ │ │ │ ├── slg/ │ │ │ │ │ │ │ │ ├── ClientSLgSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ │ ├── IClientSLgSessionData.java │ │ │ │ │ │ │ │ └── SLgClientSessionImpl.java │ │ │ │ │ │ │ └── slh/ │ │ │ │ │ │ │ ├── ClientSLhSessionDataLocalImpl.java │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IClientSLhSessionData.java │ │ │ │ │ │ │ └── SLhClientSessionImpl.java │ │ │ │ │ │ ├── controller/ │ │ │ │ │ │ │ ├── PeerImpl.java │ │ │ │ │ │ │ ├── PeerTableImpl.java │ │ │ │ │ │ │ ├── RealmImpl.java │ │ │ │ │ │ │ └── RealmTableImpl.java │ │ │ │ │ │ ├── fsm/ │ │ │ │ │ │ │ ├── FsmFactoryImpl.java │ │ │ │ │ │ │ ├── FsmState.java │ │ │ │ │ │ │ └── PeerFSMImpl.java │ │ │ │ │ │ ├── helpers/ │ │ │ │ │ │ │ ├── AppConfiguration.java │ │ │ │ │ │ │ ├── AssemblerImpl.java │ │ │ │ │ │ │ ├── EmptyConfiguration.java │ │ │ │ │ │ │ ├── ExtensionPoint.java │ │ │ │ │ │ │ ├── IPConverter.java │ │ │ │ │ │ │ ├── Loggers.java │ │ │ │ │ │ │ ├── Ordinal.java │ │ │ │ │ │ │ ├── Parameters.java │ │ │ │ │ │ │ ├── UIDGenerator.java │ │ │ │ │ │ │ └── XMLConfiguration.java │ │ │ │ │ │ ├── parser/ │ │ │ │ │ │ │ ├── AvpImpl.java │ │ │ │ │ │ │ ├── AvpSetImpl.java │ │ │ │ │ │ │ ├── ElementParser.java │ │ │ │ │ │ │ ├── MessageImpl.java │ │ │ │ │ │ │ └── MessageParser.java │ │ │ │ │ │ ├── router/ │ │ │ │ │ │ │ ├── RouterImpl.java │ │ │ │ │ │ │ ├── WeightedLeastConnectionsRouter.java │ │ │ │ │ │ │ └── WeightedRoundRobinRouter.java │ │ │ │ │ │ └── transport/ │ │ │ │ │ │ ├── TransportLayerFactory.java │ │ │ │ │ │ ├── tcp/ │ │ │ │ │ │ │ ├── TCPClientConnection.java │ │ │ │ │ │ │ ├── TCPTransportClient.java │ │ │ │ │ │ │ └── netty/ │ │ │ │ │ │ │ ├── DiameterMessageDecoder.java │ │ │ │ │ │ │ ├── DiameterMessageEncoder.java │ │ │ │ │ │ │ ├── DiameterMessageHandler.java │ │ │ │ │ │ │ ├── TCPClientConnection.java │ │ │ │ │ │ │ └── TCPTransportClient.java │ │ │ │ │ │ └── tls/ │ │ │ │ │ │ ├── TLSClientConnection.java │ │ │ │ │ │ ├── TLSTransportClient.java │ │ │ │ │ │ ├── TLSUtils.java │ │ │ │ │ │ └── netty/ │ │ │ │ │ │ ├── DiameterMessageDecoder.java │ │ │ │ │ │ ├── DiameterMessageEncoder.java │ │ │ │ │ │ ├── DiameterMessageHandler.java │ │ │ │ │ │ ├── InbandSecurityHandler.java │ │ │ │ │ │ ├── SslContextFactory.java │ │ │ │ │ │ ├── StartTlsClientHandler.java │ │ │ │ │ │ ├── StartTlsInitiator.java │ │ │ │ │ │ ├── StartTlsServerHandler.java │ │ │ │ │ │ ├── TLSClientConnection.java │ │ │ │ │ │ └── TLSTransportClient.java │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── api/ │ │ │ │ │ │ │ ├── app/ │ │ │ │ │ │ │ │ ├── AppSessionDataLocalImpl.java │ │ │ │ │ │ │ │ ├── IAppSessionData.java │ │ │ │ │ │ │ │ ├── IAppSessionDataFactory.java │ │ │ │ │ │ │ │ ├── IAppSessionFactory.java │ │ │ │ │ │ │ │ ├── IAppSessionState.java │ │ │ │ │ │ │ │ ├── acc/ │ │ │ │ │ │ │ │ │ ├── ClientAccSessionState.java │ │ │ │ │ │ │ │ │ ├── IAccMessageFactory.java │ │ │ │ │ │ │ │ │ ├── IAccSessionData.java │ │ │ │ │ │ │ │ │ ├── IAccSessionFactory.java │ │ │ │ │ │ │ │ │ ├── IClientAccActionContext.java │ │ │ │ │ │ │ │ │ ├── IServerAccActionContext.java │ │ │ │ │ │ │ │ │ └── ServerAccSessionState.java │ │ │ │ │ │ │ │ ├── auth/ │ │ │ │ │ │ │ │ │ ├── ClientAuthSessionState.java │ │ │ │ │ │ │ │ │ ├── IAuthMessageFactory.java │ │ │ │ │ │ │ │ │ ├── IAuthSessionData.java │ │ │ │ │ │ │ │ │ ├── IAuthSessionFactory.java │ │ │ │ │ │ │ │ │ ├── IClientAuthActionContext.java │ │ │ │ │ │ │ │ │ ├── IServerAuthActionContext.java │ │ │ │ │ │ │ │ │ └── ServerAuthSessionState.java │ │ │ │ │ │ │ │ ├── cca/ │ │ │ │ │ │ │ │ │ ├── ClientCCASessionState.java │ │ │ │ │ │ │ │ │ ├── ICCAMessageFactory.java │ │ │ │ │ │ │ │ │ ├── ICCASessionData.java │ │ │ │ │ │ │ │ │ ├── ICCASessionFactory.java │ │ │ │ │ │ │ │ │ ├── IClientCCASessionContext.java │ │ │ │ │ │ │ │ │ ├── IServerCCASessionContext.java │ │ │ │ │ │ │ │ │ └── ServerCCASessionState.java │ │ │ │ │ │ │ │ ├── cxdx/ │ │ │ │ │ │ │ │ │ ├── CxDxSessionState.java │ │ │ │ │ │ │ │ │ ├── ICxDxMessageFactory.java │ │ │ │ │ │ │ │ │ ├── ICxDxSessionData.java │ │ │ │ │ │ │ │ │ └── ICxDxSessionFactory.java │ │ │ │ │ │ │ │ ├── gx/ │ │ │ │ │ │ │ │ │ ├── ClientGxSessionState.java │ │ │ │ │ │ │ │ │ ├── IClientGxSessionContext.java │ │ │ │ │ │ │ │ │ ├── IGxMessageFactory.java │ │ │ │ │ │ │ │ │ ├── IGxSessionData.java │ │ │ │ │ │ │ │ │ ├── IGxSessionFactory.java │ │ │ │ │ │ │ │ │ ├── IServerGxSessionContext.java │ │ │ │ │ │ │ │ │ └── ServerGxSessionState.java │ │ │ │ │ │ │ │ ├── rf/ │ │ │ │ │ │ │ │ │ ├── ClientRfSessionState.java │ │ │ │ │ │ │ │ │ ├── IClientRfActionContext.java │ │ │ │ │ │ │ │ │ ├── IRfSessionData.java │ │ │ │ │ │ │ │ │ ├── IRfSessionFactory.java │ │ │ │ │ │ │ │ │ ├── IServerRfActionContext.java │ │ │ │ │ │ │ │ │ └── ServerRfSessionState.java │ │ │ │ │ │ │ │ ├── ro/ │ │ │ │ │ │ │ │ │ ├── ClientRoSessionState.java │ │ │ │ │ │ │ │ │ ├── IClientRoSessionContext.java │ │ │ │ │ │ │ │ │ ├── IRoMessageFactory.java │ │ │ │ │ │ │ │ │ ├── IRoSessionData.java │ │ │ │ │ │ │ │ │ ├── IRoSessionFactory.java │ │ │ │ │ │ │ │ │ ├── IServerRoSessionContext.java │ │ │ │ │ │ │ │ │ └── ServerRoSessionState.java │ │ │ │ │ │ │ │ ├── rx/ │ │ │ │ │ │ │ │ │ ├── ClientRxSessionState.java │ │ │ │ │ │ │ │ │ ├── IClientRxSessionContext.java │ │ │ │ │ │ │ │ │ ├── IRxMessageFactory.java │ │ │ │ │ │ │ │ │ ├── IRxSessionData.java │ │ │ │ │ │ │ │ │ ├── IRxSessionFactory.java │ │ │ │ │ │ │ │ │ ├── IServerRxSessionContext.java │ │ │ │ │ │ │ │ │ └── ServerRxSessionState.java │ │ │ │ │ │ │ │ ├── s13/ │ │ │ │ │ │ │ │ │ ├── IS13MessageFactory.java │ │ │ │ │ │ │ │ │ ├── IS13SessionData.java │ │ │ │ │ │ │ │ │ ├── IS13SessionFactory.java │ │ │ │ │ │ │ │ │ └── S13SessionState.java │ │ │ │ │ │ │ │ ├── s6a/ │ │ │ │ │ │ │ │ │ ├── IS6aMessageFactory.java │ │ │ │ │ │ │ │ │ ├── IS6aSessionData.java │ │ │ │ │ │ │ │ │ ├── IS6aSessionFactory.java │ │ │ │ │ │ │ │ │ └── S6aSessionState.java │ │ │ │ │ │ │ │ ├── sh/ │ │ │ │ │ │ │ │ │ ├── IShMessageFactory.java │ │ │ │ │ │ │ │ │ ├── IShSessionData.java │ │ │ │ │ │ │ │ │ └── IShSessionFactory.java │ │ │ │ │ │ │ │ ├── slg/ │ │ │ │ │ │ │ │ │ ├── ISLgMessageFactory.java │ │ │ │ │ │ │ │ │ ├── ISLgSessionData.java │ │ │ │ │ │ │ │ │ ├── ISLgSessionFactory.java │ │ │ │ │ │ │ │ │ └── SLgSessionState.java │ │ │ │ │ │ │ │ └── slh/ │ │ │ │ │ │ │ │ ├── ISLhMessageFactory.java │ │ │ │ │ │ │ │ ├── ISLhSessionData.java │ │ │ │ │ │ │ │ ├── ISLhSessionFactory.java │ │ │ │ │ │ │ │ └── SLhSessionState.java │ │ │ │ │ │ │ ├── concurrent/ │ │ │ │ │ │ │ │ ├── DummyConcurrentFactory.java │ │ │ │ │ │ │ │ ├── IConcurrentEntityFactory.java │ │ │ │ │ │ │ │ └── IConcurrentFactory.java │ │ │ │ │ │ │ ├── data/ │ │ │ │ │ │ │ │ └── ISessionDatasource.java │ │ │ │ │ │ │ ├── statistic/ │ │ │ │ │ │ │ │ ├── IStatistic.java │ │ │ │ │ │ │ │ ├── IStatisticManager.java │ │ │ │ │ │ │ │ ├── IStatisticProcessor.java │ │ │ │ │ │ │ │ └── IStatisticRecord.java │ │ │ │ │ │ │ └── timer/ │ │ │ │ │ │ │ └── ITimerFacility.java │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── DiameterUtilities.java │ │ │ │ │ │ ├── app/ │ │ │ │ │ │ │ ├── AppAnswerEventImpl.java │ │ │ │ │ │ │ ├── AppEventImpl.java │ │ │ │ │ │ │ ├── AppRequestEventImpl.java │ │ │ │ │ │ │ ├── AppSessionImpl.java │ │ │ │ │ │ │ ├── acc/ │ │ │ │ │ │ │ │ ├── AccLocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── AccSessionFactoryImpl.java │ │ │ │ │ │ │ │ ├── AccountAnswerImpl.java │ │ │ │ │ │ │ │ ├── AccountRequestImpl.java │ │ │ │ │ │ │ │ └── AppAccSessionImpl.java │ │ │ │ │ │ │ ├── auth/ │ │ │ │ │ │ │ │ ├── AbortSessionAnswerImpl.java │ │ │ │ │ │ │ │ ├── AbortSessionRequestImpl.java │ │ │ │ │ │ │ │ ├── AppAuthSessionImpl.java │ │ │ │ │ │ │ │ ├── AuthLocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── AuthSessionFactoryImpl.java │ │ │ │ │ │ │ │ ├── ReAuthAnswerImpl.java │ │ │ │ │ │ │ │ ├── ReAuthRequestImpl.java │ │ │ │ │ │ │ │ ├── SessionTermAnswerImpl.java │ │ │ │ │ │ │ │ └── SessionTermRequestImpl.java │ │ │ │ │ │ │ ├── cca/ │ │ │ │ │ │ │ │ ├── AppCCASessionImpl.java │ │ │ │ │ │ │ │ ├── CCALocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── CCASessionFactoryImpl.java │ │ │ │ │ │ │ │ ├── JCreditControlAnswerImpl.java │ │ │ │ │ │ │ │ └── JCreditControlRequestImpl.java │ │ │ │ │ │ │ ├── cxdx/ │ │ │ │ │ │ │ │ ├── CxDxLocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── CxDxLocalSessionDataImpl.java │ │ │ │ │ │ │ │ ├── CxDxSession.java │ │ │ │ │ │ │ │ ├── CxDxSessionFactoryImpl.java │ │ │ │ │ │ │ │ ├── JLocationInfoAnswerImpl.java │ │ │ │ │ │ │ │ ├── JLocationInfoRequestImpl.java │ │ │ │ │ │ │ │ ├── JMultimediaAuthAnswerImpl.java │ │ │ │ │ │ │ │ ├── JMultimediaAuthRequestImpl.java │ │ │ │ │ │ │ │ ├── JPushProfileAnswerImpl.java │ │ │ │ │ │ │ │ ├── JPushProfileRequestImpl.java │ │ │ │ │ │ │ │ ├── JRegistrationTerminationAnswerImpl.java │ │ │ │ │ │ │ │ ├── JRegistrationTerminationRequestImpl.java │ │ │ │ │ │ │ │ ├── JServerAssignmentAnswerImpl.java │ │ │ │ │ │ │ │ ├── JServerAssignmentRequestImpl.java │ │ │ │ │ │ │ │ ├── JUserAuthorizationAnswerImpl.java │ │ │ │ │ │ │ │ └── JUserAuthorizationRequestImpl.java │ │ │ │ │ │ │ ├── gq/ │ │ │ │ │ │ │ │ └── GqSessionFactoryImpl.java │ │ │ │ │ │ │ ├── gx/ │ │ │ │ │ │ │ │ ├── AppGxSessionImpl.java │ │ │ │ │ │ │ │ ├── GxCreditControlAnswerImpl.java │ │ │ │ │ │ │ │ ├── GxCreditControlRequestImpl.java │ │ │ │ │ │ │ │ ├── GxLocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── GxReAuthAnswerImpl.java │ │ │ │ │ │ │ │ ├── GxReAuthRequestImpl.java │ │ │ │ │ │ │ │ └── GxSessionFactoryImpl.java │ │ │ │ │ │ │ ├── rf/ │ │ │ │ │ │ │ │ ├── AppRfSessionImpl.java │ │ │ │ │ │ │ │ ├── RfAccountingAnswerImpl.java │ │ │ │ │ │ │ │ ├── RfAccountingRequestImpl.java │ │ │ │ │ │ │ │ ├── RfLocalSessionDataFactory.java │ │ │ │ │ │ │ │ └── RfSessionFactoryImpl.java │ │ │ │ │ │ │ ├── ro/ │ │ │ │ │ │ │ │ ├── AppRoSessionImpl.java │ │ │ │ │ │ │ │ ├── RoCreditControlAnswerImpl.java │ │ │ │ │ │ │ │ ├── RoCreditControlRequestImpl.java │ │ │ │ │ │ │ │ ├── RoLocalSessionDataFactory.java │ │ │ │ │ │ │ │ └── RoSessionFactoryImpl.java │ │ │ │ │ │ │ ├── rx/ │ │ │ │ │ │ │ │ ├── AppRxSessionImpl.java │ │ │ │ │ │ │ │ ├── RxAAAnswerImpl.java │ │ │ │ │ │ │ │ ├── RxAARequestImpl.java │ │ │ │ │ │ │ │ ├── RxAbortSessionAnswerImpl.java │ │ │ │ │ │ │ │ ├── RxAbortSessionRequestImpl.java │ │ │ │ │ │ │ │ ├── RxLocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── RxReAuthAnswerImpl.java │ │ │ │ │ │ │ │ ├── RxReAuthRequestImpl.java │ │ │ │ │ │ │ │ ├── RxSessionFactoryImpl.java │ │ │ │ │ │ │ │ ├── RxSessionTermAnswerImpl.java │ │ │ │ │ │ │ │ └── RxSessionTermRequestImpl.java │ │ │ │ │ │ │ ├── s13/ │ │ │ │ │ │ │ │ ├── JMEIdentityCheckAnswerImpl.java │ │ │ │ │ │ │ │ ├── JMEIdentityCheckRequestImpl.java │ │ │ │ │ │ │ │ ├── S13LocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── S13LocalSessionDataImpl.java │ │ │ │ │ │ │ │ ├── S13Session.java │ │ │ │ │ │ │ │ └── S13SessionFactoryImpl.java │ │ │ │ │ │ │ ├── s6a/ │ │ │ │ │ │ │ │ ├── JAuthenticationInformationAnswerImpl.java │ │ │ │ │ │ │ │ ├── JAuthenticationInformationRequestImpl.java │ │ │ │ │ │ │ │ ├── JCancelLocationAnswerImpl.java │ │ │ │ │ │ │ │ ├── JCancelLocationRequestImpl.java │ │ │ │ │ │ │ │ ├── JDeleteSubscriberDataAnswerImpl.java │ │ │ │ │ │ │ │ ├── JDeleteSubscriberDataRequestImpl.java │ │ │ │ │ │ │ │ ├── JInsertSubscriberDataAnswerImpl.java │ │ │ │ │ │ │ │ ├── JInsertSubscriberDataRequestImpl.java │ │ │ │ │ │ │ │ ├── JNotifyAnswerImpl.java │ │ │ │ │ │ │ │ ├── JNotifyRequestImpl.java │ │ │ │ │ │ │ │ ├── JPurgeUEAnswerImpl.java │ │ │ │ │ │ │ │ ├── JPurgeUERequestImpl.java │ │ │ │ │ │ │ │ ├── JResetAnswerImpl.java │ │ │ │ │ │ │ │ ├── JResetRequestImpl.java │ │ │ │ │ │ │ │ ├── JUpdateLocationAnswerImpl.java │ │ │ │ │ │ │ │ ├── JUpdateLocationRequestImpl.java │ │ │ │ │ │ │ │ ├── S6aLocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── S6aLocalSessionDataImpl.java │ │ │ │ │ │ │ │ ├── S6aSession.java │ │ │ │ │ │ │ │ └── S6aSessionFactoryImpl.java │ │ │ │ │ │ │ ├── sh/ │ │ │ │ │ │ │ │ ├── ProfileUpdateAnswerImpl.java │ │ │ │ │ │ │ │ ├── ProfileUpdateRequestImpl.java │ │ │ │ │ │ │ │ ├── PushNotificationAnswerImpl.java │ │ │ │ │ │ │ │ ├── PushNotificationRequestImpl.java │ │ │ │ │ │ │ │ ├── ShLocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── ShSession.java │ │ │ │ │ │ │ │ ├── ShSessionFactoryImpl.java │ │ │ │ │ │ │ │ ├── SubscribeNotificationsAnswerImpl.java │ │ │ │ │ │ │ │ ├── SubscribeNotificationsRequestImpl.java │ │ │ │ │ │ │ │ ├── UserDataAnswerImpl.java │ │ │ │ │ │ │ │ └── UserDataRequestImpl.java │ │ │ │ │ │ │ ├── slg/ │ │ │ │ │ │ │ │ ├── LocationReportAnswerImpl.java │ │ │ │ │ │ │ │ ├── LocationReportRequestImpl.java │ │ │ │ │ │ │ │ ├── ProvideLocationAnswerImpl.java │ │ │ │ │ │ │ │ ├── ProvideLocationRequestImpl.java │ │ │ │ │ │ │ │ ├── SLgLocalSessionDataFactory.java │ │ │ │ │ │ │ │ ├── SLgLocalSessionDataImpl.java │ │ │ │ │ │ │ │ ├── SLgSession.java │ │ │ │ │ │ │ │ └── SLgSessionFactoryImpl.java │ │ │ │ │ │ │ └── slh/ │ │ │ │ │ │ │ ├── LCSRoutingInfoAnswerImpl.java │ │ │ │ │ │ │ ├── LCSRoutingInfoRequestImpl.java │ │ │ │ │ │ │ ├── SLhLocalSessionDataFactory.java │ │ │ │ │ │ │ ├── SLhLocalSessionDataImpl.java │ │ │ │ │ │ │ ├── SLhSession.java │ │ │ │ │ │ │ └── SLhSessionFactoryImpl.java │ │ │ │ │ │ ├── concurrent/ │ │ │ │ │ │ │ ├── AbstractTask.java │ │ │ │ │ │ │ ├── BaseThreadFactory.java │ │ │ │ │ │ │ ├── CommonScheduledExecutorService.java │ │ │ │ │ │ │ ├── ConcurrentEntityFactory.java │ │ │ │ │ │ │ ├── ConcurrentFactory.java │ │ │ │ │ │ │ ├── DefaultCallable.java │ │ │ │ │ │ │ ├── DefaultRejectedExecutionHandler.java │ │ │ │ │ │ │ └── DefaultRunnable.java │ │ │ │ │ │ ├── controller/ │ │ │ │ │ │ │ └── AbstractPeer.java │ │ │ │ │ │ ├── data/ │ │ │ │ │ │ │ └── LocalDataSource.java │ │ │ │ │ │ ├── statistic/ │ │ │ │ │ │ │ ├── StatisticImpl.java │ │ │ │ │ │ │ ├── StatisticManagerImpl.java │ │ │ │ │ │ │ ├── StatisticProcessorImpl.java │ │ │ │ │ │ │ └── StatisticRecordImpl.java │ │ │ │ │ │ ├── timer/ │ │ │ │ │ │ │ └── LocalTimerFacilityImpl.java │ │ │ │ │ │ └── validation/ │ │ │ │ │ │ ├── AvpRepresentationImpl.java │ │ │ │ │ │ ├── DictionaryImpl.java │ │ │ │ │ │ └── MessageRepresentationImpl.java │ │ │ │ │ └── server/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── IFsmFactory.java │ │ │ │ │ │ ├── IMetaData.java │ │ │ │ │ │ ├── IMutablePeerTable.java │ │ │ │ │ │ ├── INetwork.java │ │ │ │ │ │ ├── IOverloadManager.java │ │ │ │ │ │ ├── IPeer.java │ │ │ │ │ │ ├── IRouter.java │ │ │ │ │ │ ├── IStateMachine.java │ │ │ │ │ │ ├── agent/ │ │ │ │ │ │ │ ├── IAgent.java │ │ │ │ │ │ │ ├── IAgentConfiguration.java │ │ │ │ │ │ │ ├── IProxy.java │ │ │ │ │ │ │ └── IRedirect.java │ │ │ │ │ │ └── io/ │ │ │ │ │ │ ├── INetworkConnectionListener.java │ │ │ │ │ │ ├── INetworkGuard.java │ │ │ │ │ │ └── ITransportLayerFactory.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── MessageValidator.java │ │ │ │ │ ├── MetaDataImpl.java │ │ │ │ │ ├── MutablePeerTableImpl.java │ │ │ │ │ ├── NetworkImpl.java │ │ │ │ │ ├── OverloadManagerImpl.java │ │ │ │ │ ├── PeerImpl.java │ │ │ │ │ ├── RouterImpl.java │ │ │ │ │ ├── StackImpl.java │ │ │ │ │ ├── StackImplMBean.java │ │ │ │ │ ├── agent/ │ │ │ │ │ │ ├── AgentConfigurationImpl.java │ │ │ │ │ │ ├── AgentImpl.java │ │ │ │ │ │ ├── ProxyAgentImpl.java │ │ │ │ │ │ └── RedirectAgentImpl.java │ │ │ │ │ ├── app/ │ │ │ │ │ │ ├── acc/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerAccSessionData.java │ │ │ │ │ │ │ ├── ServerAccSessionDataLocalImpl.java │ │ │ │ │ │ │ └── ServerAccSessionImpl.java │ │ │ │ │ │ ├── auth/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerAuthSessionData.java │ │ │ │ │ │ │ ├── ServerAuthSessionDataLocalImpl.java │ │ │ │ │ │ │ └── ServerAuthSessionImpl.java │ │ │ │ │ │ ├── cca/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerCCASessionData.java │ │ │ │ │ │ │ ├── ServerCCASessionDataLocalImpl.java │ │ │ │ │ │ │ └── ServerCCASessionImpl.java │ │ │ │ │ │ ├── cxdx/ │ │ │ │ │ │ │ ├── CxDxServerSessionImpl.java │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerCxDxSessionData.java │ │ │ │ │ │ │ └── ServerCxDxSessionDataLocalImpl.java │ │ │ │ │ │ ├── gq/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ └── GqServerSessionImpl.java │ │ │ │ │ │ ├── gx/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerGxSessionData.java │ │ │ │ │ │ │ ├── ServerGxSessionDataLocalImpl.java │ │ │ │ │ │ │ └── ServerGxSessionImpl.java │ │ │ │ │ │ ├── rf/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerRfSessionData.java │ │ │ │ │ │ │ ├── ServerRfSessionDataLocalImpl.java │ │ │ │ │ │ │ └── ServerRfSessionImpl.java │ │ │ │ │ │ ├── ro/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerRoSessionData.java │ │ │ │ │ │ │ ├── ServerRoSessionDataLocalImpl.java │ │ │ │ │ │ │ └── ServerRoSessionImpl.java │ │ │ │ │ │ ├── rx/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerRxSessionData.java │ │ │ │ │ │ │ ├── ServerRxSessionDataLocalImpl.java │ │ │ │ │ │ │ └── ServerRxSessionImpl.java │ │ │ │ │ │ ├── s13/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerS13SessionData.java │ │ │ │ │ │ │ ├── S13ServerSessionImpl.java │ │ │ │ │ │ │ └── ServerS13SessionDataLocalImpl.java │ │ │ │ │ │ ├── s6a/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerS6aSessionData.java │ │ │ │ │ │ │ ├── S6aServerSessionImpl.java │ │ │ │ │ │ │ └── ServerS6aSessionDataLocalImpl.java │ │ │ │ │ │ ├── sh/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IShServerSessionData.java │ │ │ │ │ │ │ ├── ShServerSessionDataLocalImpl.java │ │ │ │ │ │ │ └── ShServerSessionImpl.java │ │ │ │ │ │ ├── slg/ │ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ │ ├── IServerSLgSessionData.java │ │ │ │ │ │ │ ├── SLgServerSessionImpl.java │ │ │ │ │ │ │ └── ServerSLgSessionDataLocalImpl.java │ │ │ │ │ │ └── slh/ │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ ├── IServerSLhSessionData.java │ │ │ │ │ │ ├── SLhServerSessionImpl.java │ │ │ │ │ │ └── ServerSLhSessionDataLocalImpl.java │ │ │ │ │ ├── fsm/ │ │ │ │ │ │ ├── FsmFactoryImpl.java │ │ │ │ │ │ └── PeerFSMImpl.java │ │ │ │ │ ├── helpers/ │ │ │ │ │ │ ├── ApplicationIdSelector.java │ │ │ │ │ │ ├── EmptyConfiguration.java │ │ │ │ │ │ ├── ExtensionPoint.java │ │ │ │ │ │ ├── Loggers.java │ │ │ │ │ │ ├── Parameters.java │ │ │ │ │ │ └── XMLConfiguration.java │ │ │ │ │ └── io/ │ │ │ │ │ ├── TransportLayerFactory.java │ │ │ │ │ ├── tcp/ │ │ │ │ │ │ ├── NetworkGuard.java │ │ │ │ │ │ └── netty/ │ │ │ │ │ │ └── NetworkGuard.java │ │ │ │ │ └── tls/ │ │ │ │ │ ├── NetworkGuard.java │ │ │ │ │ └── netty/ │ │ │ │ │ └── NetworkGuard.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── agpl-3.0.txt │ │ │ │ │ ├── jdiameter-client.xsd │ │ │ │ │ ├── jdiameter-server.xsd │ │ │ │ │ └── version.properties │ │ │ │ └── dictionary.xml │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── jdiameter/ │ │ │ │ └── client/ │ │ │ │ └── impl/ │ │ │ │ └── router/ │ │ │ │ └── TestRouter.java │ │ │ └── resources/ │ │ │ ├── jdiameter-weightedleastconnections-config.xml │ │ │ └── jdiameter-weightedroundrobin-config.xml │ │ └── pom.xml │ ├── jdiameter-ha/ │ │ ├── api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── jdiameter/ │ │ │ └── api/ │ │ │ └── ha/ │ │ │ └── data/ │ │ │ └── CachingException.java │ │ ├── impl/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── jdiameter/ │ │ │ └── impl/ │ │ │ └── ha/ │ │ │ ├── client/ │ │ │ │ ├── acc/ │ │ │ │ │ └── ClientAccSessionDataReplicatedImpl.java │ │ │ │ ├── auth/ │ │ │ │ │ └── ClientAuthSessionDataReplicatedImpl.java │ │ │ │ ├── cca/ │ │ │ │ │ └── ClientCCASessionDataReplicatedImpl.java │ │ │ │ ├── cxdx/ │ │ │ │ │ └── ClientCxDxSessionDataReplicatedImpl.java │ │ │ │ ├── gx/ │ │ │ │ │ └── ClientGxSessionDataReplicatedImpl.java │ │ │ │ ├── rf/ │ │ │ │ │ └── ClientRfSessionDataReplicatedImpl.java │ │ │ │ ├── ro/ │ │ │ │ │ └── ClientRoSessionDataReplicatedImpl.java │ │ │ │ ├── rx/ │ │ │ │ │ └── ClientRxSessionDataReplicatedImpl.java │ │ │ │ ├── s13/ │ │ │ │ │ └── ClientS13SessionDataReplicatedImpl.java │ │ │ │ └── sh/ │ │ │ │ └── ShClientSessionDataReplicatedImpl.java │ │ │ ├── common/ │ │ │ │ ├── AppSessionDataReplicatedImpl.java │ │ │ │ ├── acc/ │ │ │ │ │ └── AccReplicatedSessionDataFactory.java │ │ │ │ ├── auth/ │ │ │ │ │ └── AuthReplicatedSessionDataFactory.java │ │ │ │ ├── cca/ │ │ │ │ │ └── CCAReplicatedSessionDataFactory.java │ │ │ │ ├── cxdx/ │ │ │ │ │ ├── CxDxReplicatedSessionDataFactory.java │ │ │ │ │ └── CxDxSessionDataReplicatedImpl.java │ │ │ │ ├── gx/ │ │ │ │ │ └── GxReplicatedSessionDataFactory.java │ │ │ │ ├── rf/ │ │ │ │ │ └── RfReplicatedSessionDataFactory.java │ │ │ │ ├── ro/ │ │ │ │ │ └── RoReplicatedSessionDataFactory.java │ │ │ │ ├── rx/ │ │ │ │ │ └── RxReplicatedSessionDataFactory.java │ │ │ │ ├── s13/ │ │ │ │ │ ├── S13ReplicatedSessionDataFactory.java │ │ │ │ │ └── S13SessionDataReplicatedImpl.java │ │ │ │ └── sh/ │ │ │ │ └── ShReplicatedSessionDataFactory.java │ │ │ ├── data/ │ │ │ │ ├── CachedSessionDatasource.java │ │ │ │ └── CachedSessionDatasourceImpl.java │ │ │ ├── server/ │ │ │ │ ├── acc/ │ │ │ │ │ └── ServerAccSessionDataReplicatedImpl.java │ │ │ │ ├── auth/ │ │ │ │ │ └── ServerAuthSessionDataReplicatedImpl.java │ │ │ │ ├── cca/ │ │ │ │ │ └── ServerCCASessionDataReplicatedImpl.java │ │ │ │ ├── cxdx/ │ │ │ │ │ └── ServerCxDxSessionDataReplicatedImpl.java │ │ │ │ ├── gx/ │ │ │ │ │ └── ServerGxSessionDataReplicatedImpl.java │ │ │ │ ├── rf/ │ │ │ │ │ └── ServerRfSessionDataReplicatedImpl.java │ │ │ │ ├── ro/ │ │ │ │ │ └── ServerRoSessionDataReplicatedImpl.java │ │ │ │ ├── rx/ │ │ │ │ │ └── ServerRxSessionDataReplicatedImpl.java │ │ │ │ ├── s13/ │ │ │ │ │ └── ServerS13SessionDataReplicatedImpl.java │ │ │ │ └── sh/ │ │ │ │ └── ShServerSessionDataReplicatedImpl.java │ │ │ └── timer/ │ │ │ └── ReplicatedTimerFacilityImpl.java │ │ └── pom.xml │ └── pom.xml ├── docs/ │ ├── antora-playbook.yml │ ├── antora.yml │ ├── modules/ │ │ └── ROOT/ │ │ ├── assets/ │ │ │ └── images/ │ │ │ └── .keepme │ │ ├── examples/ │ │ │ └── .keepme │ │ ├── nav.adoc │ │ └── pages/ │ │ ├── Author_Group.adoc │ │ ├── Book_Info.adoc │ │ ├── Chapter-Introduction.adoc │ │ ├── Chapter-JDiameter.adoc │ │ ├── Conventions.adoc │ │ ├── Diameter_User_Guide.adoc │ │ ├── Implementing-Diameter-Service.adoc │ │ ├── Java_Development_Kit-Installing_Configuring_and_Running.adoc │ │ ├── Preface.adoc │ │ ├── Revision_History.adoc │ │ ├── Section-Conventions.adoc │ │ ├── Section-Feedback.adoc │ │ ├── Section-Introduction-Message_Format.adoc │ │ ├── Section-JDiameter-Configuration.adoc │ │ ├── Section-JDiameter-Design_Overview.adoc │ │ ├── Section-JDiameter-Setup.adoc │ │ ├── Section-JDiameter-Source_Overview.adoc │ │ ├── Section-JDiameter-Validator-Configuration.adoc │ │ ├── Section-JDiameter-Validator-Source_Overview.adoc │ │ ├── Section-JDiameter-Validator.adoc │ │ ├── Setting_the_JBOSS_HOME_Environment_Variable.adoc │ │ ├── includes/ │ │ │ ├── attributes.adoc │ │ │ ├── quarkus-jdiameter.adoc │ │ │ └── quarkus-jdiameter_quarkus.diameter.adoc │ │ └── index.adoc │ ├── package.json │ ├── pom.xml │ └── templates/ │ └── includes/ │ └── attributes.adoc ├── examples/ │ ├── charging-server-simulator/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── assembly/ │ │ │ └── standalone.xml │ │ ├── java/ │ │ │ └── org/ │ │ │ └── mobicents/ │ │ │ └── servers/ │ │ │ └── diameter/ │ │ │ ├── charging/ │ │ │ │ ├── ChargingServerSimulator.java │ │ │ │ └── listeners/ │ │ │ │ └── RoClientListener.java │ │ │ └── utils/ │ │ │ ├── DiameterUtilities.java │ │ │ └── StackCreator.java │ │ └── resources/ │ │ ├── accounts.properties │ │ ├── config-server.xml │ │ ├── dictionary.xml │ │ └── log4j.properties │ └── guide1/ │ ├── bin/ │ │ ├── crun.sh │ │ └── srun.sh │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── example/ │ │ ├── client/ │ │ │ └── ExampleClient.java │ │ └── server/ │ │ └── ExampleServer.java │ └── resources/ │ ├── log4j.properties │ └── org/ │ └── example/ │ ├── client/ │ │ ├── client-jdiameter-config.xml │ │ └── dictionary.xml │ └── server/ │ ├── dictionary.xml │ └── server-jdiameter-config.xml ├── integration-tests/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── io/ │ │ │ └── quarkiverse/ │ │ │ └── jdiameter/ │ │ │ └── it/ │ │ │ └── JdiameterResource.java │ │ └── resources/ │ │ └── application.properties │ └── test/ │ └── java/ │ └── io/ │ └── quarkiverse/ │ └── jdiameter/ │ └── it/ │ ├── JdiameterResourceIT.java │ └── JdiameterResourceTest.java ├── lombok.config ├── pom.xml └── quarkus-diameter/ ├── deployment/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── io/ │ │ └── quarkiverse/ │ │ └── diameter/ │ │ └── deployment/ │ │ ├── DiameterBuildItem.java │ │ └── DiameterProcessor.java │ └── test/ │ ├── java/ │ │ └── io/ │ │ └── quarkiverse/ │ │ └── diameter/ │ │ └── deployment/ │ │ ├── DiameterConfigTest.java │ │ ├── DiameterInterceptorTest.java │ │ ├── DiameterStackTest.java │ │ └── DiameterValidatorTest.java │ └── resources/ │ └── application.properties ├── pom.xml └── runtime/ ├── pom.xml └── src/ └── main/ ├── java/ │ └── io/ │ └── quarkiverse/ │ └── diameter/ │ ├── ApplicationMode.java │ ├── DiameterApplication.java │ ├── DiameterConfig.java │ ├── DiameterService.java │ ├── DiameterServiceInterceptor.java │ ├── DiameterServiceOptions.java │ └── runtime/ │ ├── DiameterConfiguration.java │ ├── DiameterDetailConfig.java │ ├── DiameterRecorder.java │ ├── DiameterRunTimeConfig.java │ ├── DiameterSetupException.java │ ├── JDiameterVersionRecorder.java │ ├── config/ │ │ ├── Agent.java │ │ ├── ApplicationId.java │ │ ├── Concurrent.java │ │ ├── Extension.java │ │ ├── LocalPeer.java │ │ ├── Network.java │ │ ├── OverloadMonitor.java │ │ ├── Parameter.java │ │ ├── Peer.java │ │ └── Realm.java │ └── transport/ │ └── TLSClientConnection.java └── resources/ └── META-INF/ └── quarkus-extension.yaml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/CODEOWNERS ================================================ # Lines starting with '#' are comments. # Each line is a file pattern followed by one or more owners. # More details are here: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners # The '*' pattern is global owners. # Order is important. The last matching pattern has the most precedence. # The folders are ordered as follows: # In each subsection folders are ordered first by depth, then alphabetically. # This should make it easy to add new rules without breaking existing ones. * @quarkiverse/quarkiverse-jdiameter ================================================ FILE: .github/dependabot.yml ================================================ # To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "maven" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "daily" - package-ecosystem: "github-actions" directory: "/" schedule: interval: daily ================================================ FILE: .github/project.yml ================================================ release: current-version: "2.5.0" next-version: "2.5.1-SNAPSHOT" ================================================ FILE: .github/workflows/build.yml ================================================ name: Build on: push: branches: - "main" paths-ignore: - '.gitignore' - 'CODEOWNERS' - 'LICENSE' - '*.md' - '*.adoc' - '*.txt' - '.all-contributorsrc' pull_request: paths-ignore: - '.gitignore' - 'CODEOWNERS' - 'LICENSE' - '*.md' - '*.adoc' - '*.txt' - '.all-contributorsrc' permissions: contents: read pull-requests: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true defaults: run: shell: bash jobs: build: name: Build on ${{ matrix.os }} strategy: fail-fast: false matrix: # os: [windows-latest, macos-latest, ubuntu-latest] os: [ ubuntu-latest ] runs-on: ${{ matrix.os }} steps: - name: Prepare git run: git config --global core.autocrlf false if: startsWith(matrix.os, 'windows') - uses: actions/checkout@v6 - name: Set up JDK 21 uses: actions/setup-java@v5 with: distribution: temurin java-version: 21 cache: 'maven' - name: Build with Maven run: mvn -B clean install -Dno-format ================================================ FILE: .github/workflows/deploy-snapshots.yml.disabled ================================================ # This workflow will build and deploy a snapshot of your artifact to Sonatype Snapshots repository name: Deploy Snapshots concurrency: group: ${{ github.ref }}-${{ github.workflow }} cancel-in-progress: true on: workflow_dispatch: push: branches: [ main ] defaults: run: shell: bash jobs: deploy-snapshot: runs-on: ubuntu-latest name: Deploy Snapshot artifacts steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: 17 cache: 'maven' server-id: 'ossrh' server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} gpg-passphrase: MAVEN_GPG_PASSPHRASE - name: Deploy Snapshot run: | mvn -B clean deploy -DperformRelease=true -Drelease env: MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} ================================================ FILE: .github/workflows/pre-release.yml ================================================ name: Quarkiverse Pre Release on: pull_request: paths: - '.github/project.yml' permissions: contents: read pull-requests: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: pre-release: name: Pre-Release uses: quarkiverse/.github/.github/workflows/pre-release.yml@main secrets: inherit ================================================ FILE: .github/workflows/quarkus-snapshot.yaml ================================================ name: "Quarkus ecosystem CI" on: workflow_dispatch: watch: types: [started] permissions: contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build: uses: quarkiverse/.github/.github/workflows/quarkus-ecosystem-ci.yml@main secrets: inherit with: ecosystem_ci_repo_path: quarkiverse-jdiameter java_version: 21 ================================================ FILE: .github/workflows/release-perform.yml ================================================ name: Quarkiverse Perform Release run-name: Perform ${{github.event.inputs.tag || github.ref_name}} Release on: push: tags: - '*' workflow_dispatch: inputs: tag: description: 'Tag to release' required: true permissions: attestations: write id-token: write contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: perform-release: name: Perform Release uses: quarkiverse/.github/.github/workflows/perform-release.yml@main secrets: inherit with: version: ${{github.event.inputs.tag || github.ref_name}} java_version: 21 ================================================ FILE: .github/workflows/release-prepare.yml ================================================ name: Quarkiverse Prepare Release on: pull_request: types: [ closed ] paths: - '.github/project.yml' - '.github/workflows/release-prepare.yml' permissions: contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: prepare-release: name: Prepare Release if: ${{ github.event.pull_request.merged == true}} uses: quarkiverse/.github/.github/workflows/prepare-release.yml@main secrets: inherit with: java_version: 21 ================================================ FILE: .github/workflows/release.yml.disabled ================================================ name: Quarkiverse Release on: pull_request: types: [ closed ] paths: - '.github/project.yml' - '.github/workflows/release.yml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true defaults: run: shell: bash jobs: release: runs-on: ubuntu-latest name: release if: ${{github.event.pull_request.merged == true}} steps: - uses: radcortez/project-metadata-action@main name: Retrieve project metadata id: metadata with: github-token: ${{secrets.GITHUB_TOKEN}} metadata-file-path: '.github/project.yml' - uses: actions/checkout@v4 - name: Set up JDK 21 uses: actions/setup-java@v4.2.2 with: distribution: temurin java-version: 21 cache: 'maven' server-id: ossrh server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} gpg-passphrase: MAVEN_GPG_PASSPHRASE - name: Set up Maven 3.9.6 uses: stCarolas/setup-maven@v5 with: maven-version: 3.9.6 - name: Configure Git author run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - name: Update latest release version in docs run: | mvn -B -ntp -pl docs -am package -DskipTests -DskipITs -Denforcer.skip -Dformatter.skip -Dimpsort.skip if ! git diff --quiet docs/modules/ROOT/pages/includes; then git add docs/modules/ROOT/pages/includes git commit -m "Update the latest release version ${{steps.metadata.outputs.current-version}} in documentation" fi - name: Maven release ${{steps.metadata.outputs.current-version}} run: | mvn -B release:prepare -Prelease -DreleaseVersion=${{steps.metadata.outputs.current-version}} -DdevelopmentVersion=${{steps.metadata.outputs.next-version}} mvn -B release:perform -Darguments=-DperformRelease -DperformRelease -Prelease env: MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - name: Push changes to ${{github.base_ref}} branch run: | git push git push origin ${{steps.metadata.outputs.current-version}} ================================================ FILE: .gitignore ================================================ # Java compiled # ################# *.class # Eclipse # ########### .classpath .project .settings # IntelliJ IDEA # ################# .idea/ *.iml *.iws # Maven # ######### target \$\{env.JBOSS_HOME\} # OS generated files # ###################### .DS_Store .DS_Store? ._* .Spotlight-V100 .Trashes Icon? ehthumbs.db Thumbs.db #ascidoc **/node_modules/ package-lock.json **/cache/ ================================================ FILE: LICENSE ================================================ GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . ================================================ FILE: README.md ================================================ # Quarkus Diameter Stack [![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) [![Build](https://github.com/quarkiverse/quarkus-jdiameter/actions/workflows/build.yml/badge.svg?style=for-the-badge)](https://github.com/quarkiverse/quarkus-jdiameter/actions/workflows/build.yml) [![Maven Central](https://img.shields.io/maven-central/v/io.quarkiverse.jdiameter/quarkus-jdiameter.svg?label=Maven%20Central&style=flat-square)](https://search.maven.org/artifact/io.quarkiverse.jdiameter/quarkus-jdiameter) [![GitHub](https://img.shields.io/github/license/quarkiverse/quarkus-jdiameter?color=blue&style=flat-square)](https://github.com/quarkiverse/quarkus-jdiameter/blob/main/LICENSE) This is a fork of the RestComm jDiameter Stack with a couple of enhancements done: - Update the minimum java compatibility to Java 21 - Added support for Virtual Threading - Removed use of Pico Containers - Added Quarkus Extension - Updated all the dependencies to latest versions - Removed support for SCTP protocol (Not used and deprecated for 5G) - Reworked the jdiameter-ha component to use Infinispan as the caching provider **NOTE**: This is a community extension, and it is not related nor supported by RestComm Ltd. ## Virtual Threading There is now a new parameter called "UseVirtualThreads" that if set to true will use virtual threads for the diameter stack. To use virtual threading, the minimum supported Java version had to be changed to Java 21. ## Quarkus Extension The extension allows for the injection of configurations and stacks. See the docs folder for the relevant documentation. ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Chapter-Introduction.adoc~ ================================================ [[_introduction]] = Introduction to &THIS.PLATFORM; Diameter Diameter is a computer networking protocol for Authentication, Authorization and Accounting (), as defined in RFC3588. It is a successor to RADIUS, and has been designed to overcome certain RADIUS limitations: * No transport reliability and flexibility (Diameter uses TCP/SCTP instead of UDP). * No security within protocol (Diameter supports IPSec (mandatory) and TLS (optional)). * Limited address space for AVPs (Diameter uses 32-bit address space instead of 8-bit). * Only stateless mode is possible (Diameter supports both stateful and stateless modes). * Static peers (Diameter offers dynamic discovery, using DNS, SRV and NAPTR). * No peer alignment capabilities (Diameter introduces capabilities negotiation). * No support for transport layer failover. Diameter follows http://tools.ietf.org/html/rfc3539[RFC3539], which introduces correct procedures. * Limited support for roaming (Diameter introduces mechanisms for secure and scalable roaming). * No extension possible (Diameter allows extension - new commands and AVPs to be defined). Diameter offers all of the capabilities of the RADIUS protocol, and is compatible with RADIUS. It can also define extensions, or "Applications". Each application may introduce new types of messages, AVP codes, and state machines. The Message and AVP codes are assigned by the . Each application has its own Application ID and Vendor ID that is used to distinguish between applications. Application code is used to signal to other peers which operations are supported by the connecting peer (Capabilities Exchange / Negotiation). :leveloffset: +1 include::Section-Introduction-Message_Format.adoc[] :leveloffset: -1 [[_introduction_contents]] == Contents &THIS.PLATFORM;Diameter core is built on top of three basic components: Stack:: Extensible Diameter Stack. It provides basic session support along with application specific sessions. Multiplexer (MUX):: Diameter Stack multiplexer. Allows different listeners to share the same stack instance. Dictionary:: Diameter Message and AVP Dictionary. Provides an API to access information about AVPs. Dictionary is embeded in the MUX. ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Chapter-JDiameter.adoc~ ================================================ [[_jdiameter]] = {this-platform} Diameter Stack The Diameter Stack is the core component of the presented Diameter solution. It performs all necessary tasks to allow user interaction with the Diameter network. It manages the state of diameter peers and allows to route messages between them. For more details, refer to http://tools.ietf.org/html/rfc3588[RFC 3588]. The Diameter Stack currently supports the following application sessions: * Base * Credit Control Application (CCA) * Sh * Ro * Rf * Cx/Dx * Gx * Gq' * Rx :leveloffset: 1 include::Section-JDiameter-Design_Overview.adoc[] :leveloffset: 0 :leveloffset: 1 include::Section-JDiameter-Setup.adoc[] :leveloffset: 0 :leveloffset: 1 include::Section-JDiameter-Configuration.adoc[] :leveloffset: 0 :leveloffset: 1 include::Section-JDiameter-Source_Overview.adoc[] :leveloffset: 0 :leveloffset: 1 include::Section-JDiameter-Validator.adoc[] :leveloffset: 0 ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Chapter-MUX.adoc~ ================================================ [[_mux]] = Multiplexer (MUX) The Multiplexer (MUX) is designed as a stack wrapper. It serves two purposes: Expose Stack:: It exposes the stack and allows it to be shared between multiple listeners. The stack follows the life cycle of the MUX. It is created and destroyed with MUX. Expose Management Operations:: Exposes the management operations for clients, one of them being the &MANAGEMENT.PLATFORM; Console. For specific information please refer to the &THIS.PLATFORM; Diameter Management Console User Guide. :leveloffset: +1 include::Section-MUX-Design_Overview.adoc[] :leveloffset: -1 :leveloffset: +1 include::Section-MUX-Setup.adoc[] :leveloffset: -1 :leveloffset: +1 include::Section-MUX-Configuration.adoc[] :leveloffset: -1 :leveloffset: +1 include::Section-MUX-Source_Overview.adoc[] :leveloffset: -1 :leveloffset: +1 include::Section-MUX-Dictionary.adoc[] :leveloffset: -1 ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Diameter_User_Guide.adoc~ ================================================ = User Guide to {this-platform} {this-application} {project-version} :doctype: book :sectnums: :toc: left :icons: font :experimental: :sourcedir: . :leveloffset: 1 include::Book_Info.adoc[] :leveloffset: 0 :leveloffset: 1 include::common/Preface.adoc[] :leveloffset: 0 :leveloffset: 1 include::Chapter-Introduction.adoc[] :leveloffset: 0 :leveloffset: 1 include::Chapter-JDiameter.adoc[] :leveloffset: 0 :leveloffset: 1 include::Chapter-MUX.adoc[] :leveloffset: 0 :leveloffset: 1 include::Revision_History.adoc[] :leveloffset: 0 ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Section-Introduction-Message_Format.adoc~ ================================================ [[_mf_message_format]] = Message Format Diameter is a byte based protocol. Each message has a fixed structure, which consists of two parts: header and payload. The message header structure is common for every message. The content is fixed, as is the length. Message header content includes the code, application and certain bit flags, which helps identify the message in Diameter scope. The message payload is built up of AVPs. Its content differs for each command and application, though they all define the Session-ID AVP as mandatory. .Diameter Message Structure image::images/dia-Introduction-dia-DiameterPacketFormat.png[] The header has the following fields: .Message Headers Version:: Indicates the Diameter protocol version. This value is always set to `1`. Message Length:: Indicates the Diameter message length, including the header fields. Flags:: Composed by eight bits, to provide information regarding the message. The first four bits in the flags octet have the following meaning: * R = The message is a request (1) or an answer (0). * P = The message is proxiable (1) and may be proxied, relayed or redirected, or it must be processed locally (0). * E = The message is an error message (1) or a regular message (0). * T = The message is potentially being re-transmitted (1) or being sent for the first time (0). The last four bits are reserved for future use, and should be set to 0. Command Code:: Indicates the command associated with the message. Application-ID:: Identifies the application to which the message is applicable for. The application is an authentication, accounting, or vendor specific application. The `application-id` in the header must be the same as what is contained in any relevant AVPs in the message. Hop-by-Hop ID:: A unique ID that is used to match requests and answers. The header field of the answer message must contain the same value present in the corresponding request. This is how answers are routed back to the peer that sent the message. End-to-End ID:: A time-limited unique ID that is used to to detect duplicate messages. The ID must be unique for at least four minutes. The answer message originator must ensure that this header contains the same value present in the corresponding request. The message payload is built up from AVPs. Each AVP has a similar structure: a header, and encoded data. Data can be simple (eg, integer, long) or complex (another encoded AVP). .Payload Structure image::images/dia-Introduction-dia-DiameterAVPLayout.png[] .Payload AVPs AVP Code:: Uniquely identifies the attribute, by combining the specified code with the value contained within the Vendor-ID header field. AVP numbers 1 to 255 are reserved for RADIUS backwards compatibility, and do not require the Vendor-ID header field. AVP numbers 256 and above are used exclusively for the Diameter protocol, and are allocated by IANA. Flags:: Bit flags that specify how each attribute must be handled. Flags octets have the following structure: V M P r r r r r. A full description is available in http://tools.ietf.org/html/rfc3588#section-4.1[Section 4.1 of RFC3588]. The first three bits have the following meaning: * V If set, indicates that optional octets (Vendor-ID) is present in AVP header. * M If set, it indicates that receiveing peer must understand this AVP or send error answer. * P If set, it indicates the need for encryption for end-to-end security. The last 5 bits are reserved for future use, and should be set to 0. AVP Length:: Indicates the number of octets in the AVP, including the following information: Vendor-ID:: An optional octet that identifies the AVP in application space. AVP code and AVP Vendor-ID create a unique identifier for the AVP. ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Configuration.adoc~ ================================================ [[_jdiameter_configuration]] = Diameter Stack Configuration The stack is initially configured by parsing an XML file. The top level structure of the file is described below. Further explanation of each child element, and the applicable attributes, is provided later in this section. [source,xml] ---- ---- [source,xml] ---- ---- The element contains parameters that affect the local Diameter peer. The available elements and attributes are listed for reference. . Elements and Attributes :: Specifies the URI for the local peer. The URI has the following format: "aaa://FQDN:port". :: Contains one or more child element, which contain a single, valid IP address for the local peer, stored in the [parameter]`value` attribute of the IPAddress. :: Specifies the realm of the local peer, using the [parameter]`value` attribute. :: Specifies a numeric identifier that corresponds to the vendor ID allocated by IANA. :: Specifies the name of the local peer product. :: Specifies the version of the firmware. :: Optional parent element containing child elements that specify settings relating to the Overload Monitor. :: Supports child elements that specify the ID of the tracked application(s). It also supports the following properties: index Defines the index of this overload monitor, so priorities/orders can be specified. lowThreshold The low threshold for activation of the overload monitor. highThreshold The high threshold for activation of the overload monitor. :: Parent element containing child elements that specify information about the application. The child elements create a unique application identifier. The child elements are: Specifies the vendor ID for application definition. It supports a single property: "value". The Authentication Application ID for application definition. It supports a single property: "value". The Account Application ID for application definition. It supports a single property: "value". :: Contains a child element , which defines the list of default supported applications. It is used for the server side, when the stack is configured to accept incoming calls and there is an empty list of preconfigured peers (server is configured to accept any connection). [source,xml] ---- ---- The element contains elements that specify parameters for the Diameter stack. The available elements and attributes are listed for reference. If not specified otherwise, each tag supports a single property - "value", which indicates the value of the tag. . Elements and Attributes :: Specifies whether the stack will accept connections from undefined peers. The default value is `false`. :: Specifies whether duplicate message protection is enabled. The default value is `false`. :: Specifies the time each duplicate message is valid for (in extreme cases, it can live up to 2 * DuplicateTimer - 1 milliseconds). The default, minimum value is `240000` (4 minutes in milliseconds). :: Specifies the number of requests stored for duplicate protection. The default value is `5000`. :: Determines whether the URI should be used as FQDN. If it is set to `true`, the stack expects the destination/origin host to be in the format of "aaa://isdn.domain.com:3868" rather than the normal "isdn.domain.com". The default value is `false`. :: Determines how many tasks the peer state machine can have before rejecting the next task. This queue contains FSM events and messaging. :: Determines the timeout for messages other than protocol FSM messages. The delay is in milliseconds. :: Determines how long the stack waits for all resources to stop. The delays are in milliseconds. :: Determines how long it takes for CER/CEA exchanges to timeout if there is no response. The delays are in milliseconds. :: Determines how long the stack waits to retry the communication with a peer that has stopped answering DWR messages. The delay is in milliseconds. :: Determines how long it takes for a DWR/DWA exchange to timeout if there is no response. The delay is in milliseconds. :: Determines how long it takes for a DPR/DPA exchange to timeout if there is no response. The delay is in milliseconds. :: Determines how long it takes for the reconnection procedure to timeout. The delay is in milliseconds. :: Determines the number of threads for handling events in the Peer FSM. :: Controls the thread pool sizes for different aspects of the stack. It supports multiple [parameter]`Entity` child elements. [parameter]`Entity` elements configure thread groups. These elements support the following properties: name Specifies the name of the entity. size Specifies the thread pool size of the entity. The default supported entities are: ThreadGroup Determines the maximum thread count in other entities. ProcessingMessageTimer Determines the thread count for message processing tasks. DuplicationMessageTimer Specifies the thread pool for identifying duplicate messages. RedirectMessageTimer Specifies the thread pool for redirecting messages that do not need any further processing. PeerOverloadTimer Determines the thread pool for managing the overload monitor. ConnectionTimer Determines the thread pool for managing tasks regarding peer connection FSM. StatisticTimer Determines the thread pool for statistic gathering tasks. ApplicationSession Determines the thread pool for managing the invocation of application session FSMs, which will invoke listeners. [source,xml] ---- ---- The element contains elements that specify parameters for external peers. The available elements and attributes are listed for reference. . Elements and Attributes :: Parent element containing the child element , which specifies external peers and the way they connect. specifies the name of external peers, whether they should be treated as a server or client, and what rating the peer has externally. supports the following properties: name Specifies the name of the peer in the form of a URI. The structure is "aaa://[fqdn|ip]:port" (for example, "aaa://192.168.1.1:3868"). attempt_connect Determines if the stack should try to connect to this peer. This property accepts boolean values. rating Specifies the rating of this peer in order to achieve peer priorities/sorting. :: Parent element containing the child element , which specifies all realms that connect into the Diameter network. contains attributes and elements that describe different realms configured for the Core. It supports child elements, which define the applications supported. supports the following parameters: peers Comma separated list of peers. Each peer is represented by an IP Address or FQDN. local_action Determines the action the Local Peer will play on the specified realm: Act as a LOCAL peer. dynamic Specifies if this realm is dynamic. That is, peers that connect to peers with this realm name will be added to the realm peer list if not present already. exp_time The time before a peer belonging to this realm is removed if no connection is available. Below is an example configuration file for a server supporting the CCA, Sh and Ro Applications: [source,xml] ---- ---- [[_jdiameter_cluster_configuration]] == Cluster configuration The following list defines the requirements for enabling stack cluster mode * Add the following entries to the `Parameters` section of [path]_jdiameter-config.xml_: + [source,xml] ---- org.mobicents.diameter.impl. ha.data.ReplicatedData org.mobicents.diameter.impl.ha. timer.ReplicatedTimerFacilityImpl ---- * A proper `JBoss Cache` configuration file: [path]_jdiameter-jbc.xml_ (located in the [path]_config_ directory). + The following content is sufficient for the JBoss Cache configuration file: + [source,xml] ---- ---- ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Setup.adoc~ ================================================ [[_jdiameter_setup]] = {this-platform} Diameter Stack Setup [[_jdiameter_preinstall_requirements_and_prerequisites]] == Pre-Install Requirements and Prerequisites Ensure that the following requirements have been met before continuing with the install. [[_jdiameter_hardware_requirements]] === Hardware Requirements {this-platform} Diameter Stack does not have any hardware requirements. [[_jdiameter_software_prerequisites]] === Software Prerequisites {this-platform} Diameter Stack has the following software dependencies: * Pico Container * slf4j Clustered setup also requires following: * JDiameter HA * JBoss Cache [[_jdiameter_source_code]] == Source Code This section provides instructions on how to obtain and build the {this-platform} Diameter Stack from source code. [[_jdiameter_release_source_building]] === Release Source Code Building . Downloading the source code + IMPORTANT: Subversion is used to manage its source code. Instructions for using Subversion, including install, can be found at http://svnbook.red-bean.com + Use SVN to checkout a specific release source, the base URL is {this-trunk-source-code-url} , then add the specific release version, lets consider &THIS.VERSION;. + [source] ---- [usr]$ git clone git@github.com:RestComm/jss7.git ---- . Building the source code + IMPORTANT: Maven 3.2.5 (or higher) is used to build the release. Instructions for using Maven2, including install, can be found at http://maven.apache.org + Use Maven to build the deployable unit binary. + [source] ---- [usr]$ cd - [usr]$ mvn install ---- + Once the process finishes you should have the files deployed in maven archive. [[_jdiameter_trunk_source_building]] === Development Trunk Source Building Follow the process in <<_jdiameter_release_source_building>>, replacing the SVN source code URL with &THIS.JDIAMETER_TRUNK_SOURCE_CODE_URL;. ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Source_Overview.adoc~ ================================================ [[_jdiameter_source_overview]] = Diameter Stack Source overview Diameter stack is built with the following basic components: Session Factory:: The Session Factory governs the creation of sessions - raw and specific application sessions. Raw and Application Sessions:: Sessions govern stateful message routing between peers. Specific application sessions consume different type of messages and act differently based on the data present. Stack:: The Stack governs all necessary components, which are used to establish connection and communicate with remote peers. NOTE: For more detailed information, please refer to the Javadoc or the simple examples that can be found here: https://github.com/RestComm/jdiameter/tree/master/testsuite/load[Git Testsuite HEAD]. [[_jdiameter_source_overview_session_factory]] == Session Factory [class]`SessionFactory` provides the stack user with access to session objects. It manages registered application session factories in order to allow for the creation of specific application sessions. A Session Factory instance can be obtained from the stack using the [method]`getSessionFactory()` method. The base [class]`SessionFactory` interface is defined below: [source,java] ---- package org.jdiameter.api; import org.jdiameter.api.app.AppSession; public interface SessionFactory { RawSession getNewRawSession() throws InternalException; Session getNewSession() throws InternalException; Session getNewSession(String sessionId) throws InternalException; T getNewAppSession(ApplicationId applicationId, Class userSession) throws InternalException; T getNewAppSession(String sessionId, ApplicationId applicationId, Class userSession) throws InternalException; } ---- However, since the stack is extensible, it is safe to cast the [class]`SessionFactory` object to this interface: [source,java] ---- package org.jdiameter.client.api; public interface ISessionFactory extends SessionFactory { T getNewAppSession(String sessionId, ApplicationId applicationId, java.lang.Class aClass, Object... args) throws InternalException; void registerAppFacory(Class sessionClass, IAppSessionFactory factory); void unRegisterAppFacory(Class sessionClass); IConcurrentFactory getConcurrentFactory(); } ---- [method]`RawSession getNewRawSession() throws InternalException;`:: This method creates a [class]`RawSession`. Raw sessions are meant as handles for code performing part of the routing decision on the stack's, such as rely agents for instance. [method]`Session getNewSession() throws InternalException;`:: This method creates a session that acts as the endpoint for peer communication (for a given session ID). It declares the method that works with the [class]`Request` and [class]`Answer` objects. A session created with this method has an autogenerated ID. It should be considered as a client session. [method]`Session getNewSession(String sessionId) throws InternalException;`:: As above. However, the created session has an ID equal to that passsed as an argument. This created session should be considered a server session. [method]` T getNewAppSession(ApplicationId applicationId, Class userSession) throws InternalException;`:: This method creates a new specific application session, identified by the application ID and class of the session passed. The session ID is generated by implementation. New application sessions should be considered as client sessions. It is safe to type cast the return value to class passed as an argument. This method delegates the call to a specific application session factory. [method]` T getNewAppSession(String sessionId, ApplicationId applicationId, Class userSession) throws InternalException;`:: As above. However, the session Id is equal to the argument passed. New sessions should be considered server sessions. [method]` T getNewAppSession(String sessionId, ApplicationId applicationId, java.lang.Class aClass, Object... args) throws InternalException;`:: As above. However, it allows the stack to pass some additional arguments. Passed values are implementation specifc. [method]`void registerAppFacory(Class sessionClass, IAppSessionFactory factory);`:: Registers the [parameter]`factory` for a certain [parameter]`sessionClass`. This factory will receive a delegated call when ever the [method]`getNewAppSession` method is called with an application class matching one from the register method. [method]`void unRegisterAppFacory(Class sessionClass);`:: Removes the application session factory registered for the [parameter]`sessionClass`. .SessionFactory use example ==== [source,java] ---- class Test implements EventListener { .... public void test(){ Stack stack = new StackImpl(); XMLConfiguration config = new XMLConfiguration(new FileInputStream(new File(configFile)); SessionFactory sessionFactory = stack.init(config); stack.start(); //perferctly legal, both factories are the same. sessionFactor = stack.getSessionFactory(); Session session = sessionFactory.getNewSession(); session.setRequestListener(this); Request r = session.createRequest(308,ApplicationId.createByAuth(100L,10101L), "mobicents.org","aaa://uas.fancyapp.mobicents.org"); //add avps specific for app session.send(r,this); } } ---- ==== .SessionFactory use example ==== [source,java] ---- class Test implements EventListener { Stack stack = new StackImpl(); XMLConfiguration config = new XMLConfiguration(new FileInputStream(new File(configFile)); ISessionFactory sessionFactory = (ISessionFactory)stack.init(config); stack.start(); //perferctly legal, both factories are the same. sessionFactor = (ISessionFactory)stack.getSessionFactory(); sessionFactory.registerAppFacory(ClientShSession.class, new ShClientSessionFactory(this)); //our implementation of factory does not require any parameters ClientShSession session = (ClientShSession) sessionFactory.getNewAppSession(null, null , ClientShSession.class, null); ... session.sendUserDataRequest(udr); } ---- ==== [[_jdiameter_source_overview_session]] == Sessions [class]`RawSessions`, [class]`Sessions` and [class]`ApplicationSessions` provide the means for dispatching and receiving messages. Specific implementation of [class]`ApplicationSession` may provide non standard methods. The [class]`RawSession` and the [class]`Session` life span is controlled entirely by the application. However, the [class]`ApplicationSession` life time depends on the implemented state machine. [class]`RawSession` is defined as follows: [source,java] ---- public interface BaseSession extends Wrapper, Serializable { long getCreationTime(); long getLastAccessedTime(); boolean isValid(); Future send(Message message) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; Future send(Message message, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void release(); } public interface RawSession extends BaseSession { Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp); Message createMessage(int commandCode, ApplicationId applicationId, long hopByHopIdentifier, long endToEndIdentifier, Avp... avp); Message createMessage(Message message, boolean copyAvps); void send(Message message, EventListener listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ---- [method]`long getCreationTime();`:: Returns the time stamp of this session creation. [method]`long getLastAccessedTime();`:: Returns the time stamp indicating the last sent or received operation. [method]`boolean isValid();`:: Returns `true` when this session is still valid (ie, [method]`release()` has not been called). [method]`void release();`:: Application calls this method to inform the user that the session should free any associated resource - it shall not be used anymore. [method]`Future send(Message message)`:: Sends a message in async mode. The [class]`Future` reference provides the means of accessing the answer once it is received [method]`void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit)`:: As above. Allows to specify the time out value for send operations. [method]`Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp);`:: Creates a Diameter message. It should be explicitly set either as a request or answer. Passed parameters are used to build messages. [method]`Message createMessage(int commandCode, ApplicationId applicationId, long hopByHopIdentifier, long endToEndIdentifier, Avp... avp);`:: As above. However, it also allows for the Hop-by-Hop and End-to-End Identifiers in the message header to be set. This method should be used to create answers. [method]`Message createMessage(Message message, boolean copyAvps);`:: Clones a message and returns the created object. The copyAvps parameter defines whether basic AVPs (Session, Route and Proxy information) should be copied to the new object. [method]`void send(Message message, EventListener listener)`:: Sends a message. The answer will be delivered by the specified listener [method]`void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit)`:: As above. It also allows for the answer to be passed after timeout. [class]`Session` defines similar methods, with exactly the same purpose: [source,java] ---- public interface Session extends BaseSession { String getSessionId(); void setRequestListener(NetworkReqListener listener); Request createRequest(int commandCode, ApplicationId appId, String destRealm); Request createRequest(int commandCode, ApplicationId appId, String destRealm, String destHost); Request createRequest(Request prevRequest); void send(Message message, EventListener listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ---- == Application Session Factories In the table below, you can find session factories provided by current implementation, along with a short description: .Application Factories [cols="1,1,1,1", frame="all", options="header"] |=== | Factory class | Application type & id | Application | Reference | RFC3588 | RFC3588 | RFC4006 | TS.29328, TS.29329 | TS.29228, TS.29229 | TS.29228, TS.29229 | TS.32240 | TS.32240 |=== NOTE: There is no specific factory for Ro and Rf. Those applications reuse the respective session and session factories. NOTE: Application IDs contain two numbers - [VendorId:ApplicationId]. IMPORTANT: Spaces have been introduced in the `Factory class` column values to correctly render the table. Please remove them when using copy/paste. ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Configuration.adoc~ ================================================ [[_jdiameter_validator_configuration]] = Validator Configuration The Validator is configured with a single XML file. This file contains the structure definition for both messages and AVPs. Upon creation of the Diameter Stack, the validator is initialized. It performs the initialization by looking up the [path]_dictionary.xml_ file in classpath. NOTE: The configuration file contains more data that `Validator` uses to build its data base. This is because the `Dictionary` uses the same file to configure itself. It reuses the AVP definitions, with some extra information like AVP type and flags. The configuration file has the following structure: [source,xml] ---- ---- :: The root element that contains the child elements comprising the validator and dictionary components. This element does not support any attributes. :: Specifies whether message validation is activated for sent and received stack messages. The element supports the following optional attributes: enabled Specifies whether the validator is activated or deactivated. If not specified, the validator is deactivated. sendLevel Determines the validation level for messages sent by the stack instance. Values determine if sent messages are not validated at all (OFF), only message level AVPs are checked (MESSAGE) or all AVPs are checked (ALL). receiveLevel Determines the validation level for messages received by the stack instance. Values determine if sent messages are not validated at all (OFF), only message level AVPs are checked (MESSAGE) or all AVPs are checked (ALL). :: Optional element that specifies the mapping between the vendor name, vendor ID, and vendor code. The element supports the following required attributes: name Specifies the vendor name. For example, "Hewlett Packard". vendor-id Specifies the unique ID associated with the vendor. For example, "HP". code Specifies the alpha-numeric code allocated to the vendor by IANA. For example, "11". The value must be unique for each declaration. . XML Attributes ==== [source,xml] ---- ... ---- ==== :: Defines the simple Attribute Value Pair (AVP) types. The element supports the following required attributes: type-name Specifies a type name in accordance with the acceptable base types defined in RFC 3588. For example; "Enumerated", "OctetString", "Integer32". type-parent Specifies the parent type name used to define the base characteristics of the type. The values are restricted to defined elements. For example; "OctetString", "UTF8String", "IPAddress". . XML Attributes ==== [source,xml] ---- ---- ==== :: Defines the specific applications used within the dictionary. Two child elements are supported by : and . The element supports the following attributes: id Specifies the unique ID allocated to the application. The attribute is used in all messages and forms part of the message header. name Optional attribute that specifies the logical name of the application. uri Optional attribute that specifies a link to additional application information. . XML Attributes ==== [source,xml] ---- ---- ==== :: Element containing information necessary to configure the Attribute Value Pairs. <<_table_avp_attributes>> contains the complete list of supported attributes, and their available values (if applicable). The element supports a number of child elements that are used to set finer parameters for the individual AVP. The supported elements are , , and . NOTE: Different sets of elements are supported by depending on its position in the dictionary.xml file. . Child Elements and Attributes ==== [source,xml] ---- ---- ==== :: Child element of that is used to match the AVP with the AVP type as defined in the element. The element supports the following mandatory attribute: type-name Specifies the type-name of the element. This is used to match the type-name value in the element. NOTE: is ignored if the element contains the element. :: Child element of that specifies the enumeration value for the specified AVP. is used only when the type-name attribute of is specified. The element supports the following mandatory attributes: name Specifies the name of a constant value that applies to the AVP. code Specifies the integer value associated with the name of the constant. The value is passed as a value of the AVP, and maps to the name attribute. NOTE: is ignored if the element contains the element. :: Child element of that specifies the AVP is a grouped type. A grouped AVP is one that has no element present. The element does not support any attributes, however the element is allowed as a child element. The , which specifies a reference to a grouped AVP, supports one mandatory attribute: name Specifies the name of the grouped AVP member. The value must match the defined AVP name. . Attributes [cols="1,1,1", frame="all", options="header"] |=== | Attribute Name (optional in brackets) | Explicit Values (default in brackets) | Description | name | | Specifies the name of the AVP. This is used to match the AVP definition to any grouped AVP references. For further information about grouped AVPs, refer to the element description in this section. | code | | Specifies the integer code of the AVP. | (vendor-id) | (none) | Used to match the vendor ID reference to the value defined in the element. | (multiplicity) | | Specifies the number of acceptable AVPs in a message using an explicit value. | | 0 | An AVP must not be present in the message. | | (0+) | Zero or more instances of the AVP must be present in the message. | | 0-1 | Zero, or one instance of the AVP may be present in the message. An error occurs if the message contains more than one instance of the AVP. | | 1 | One instance of the AVP must be present in the message. | | 1+ | At least one instance of the AVP must be present in the message. | may-encrypt | Yes \| (No) | Specifies whether the AVP can be encrypted. | protected | may \| must \| mustnot | Determines actual state of AVP that is expected, if it MUST be encrypted , may or MUST NOT. | vendor-bit | must \| mustnot | Specifies whether the Vendor ID should be set. | mandatory | may \| must \| mustnot | Determines if support for this AVP is mandatory in order to consume/process message. | vendor | | Specifies the defined vendor code, which is used by the child element |=== . XML Attributes ==== [source,xml] ---- ---- ==== :: Specifies the command for the application. The element supports the element, which specifies the structure of the command. The element supports the following attributes: NOTE: If the element is specified in , it does not support any child elements. The element only refers to defined AVPs when used in this context. . Elements and Attributes ==== [source,xml] ---- ---- ==== ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator-Source_Overview.adoc~ ================================================ [[_jdiameter_validator_source_overview]] = Validator Source Overview The Validator API defines methods to access its database of AVPs and check if the AVP and message have the proper structure. The Validator is currently message oriented. This means that it declares methods that center on message consistency checks. The class containing all validation logic is [class]`org.jdiameter.common.impl.validation.DiameterMessageValidator`. It exposes the following methods: public boolean isOn();:: Simple method to determine if the `Validator` is enabled. public ValidatorLevel getSendLevel(); :: Returns the validation level of outgoing messages. It can have one of the following values: `OFF`, `MESSAGE`, `ALL`. public ValidatorLevel getReceiveLevel():: Returns the validation level of incoming messages. It can have one of the following values: `OFF`, `MESSAGE`, `ALL`. public void validate(Message msg, boolean incoming) throws JAvpNotAllowedException:: Performs validation on a message. Based on the [parameter]`incoming` flag, the correct validation level is applied. If validation fails, an exception with details is thrown. public void validate(Message msg, ValidatorLevel validatorLevel) throws JAvpNotAllowedException:: Performs validation on messages with a specified level. It is a programatical way to allow different levels of validation from those configured. If validation fails, a [class]`JAvpNotAllowedException` with details is thrown. NOTE: The current implementation provides more methods, however those are out of scope for this documentation. A simple example of a Validator use case is shown below: .Validator Message Check Example ==== The example below is pseudo-code. [source,java] ---- ... boolean isRequest = true; boolean isIncoming = false; DiameterMessageValidator messageValidator = DiameterMessageValidator.getInstance(); Message message = createMessage(UserDataRequest.MESSAGE_CODE, isRequest, applicationId); //add AVPs ... //perform check try{ messageValidator.validate(message, isIncoming); } catch(JAvpNotAllowedException e) { System.err.println("Failed to validate ..., avp code: " + e.getAvpCode() + " avp vendor:" + e.getVendorId() + ", message:" + e.getMessage()); } ---- ==== ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Section-JDiameter-Validator.adoc~ ================================================ [[_jdiameter_validator]] = Diameter Stack Validator Validator is one of the Stack features. The primary purpose of the Validator is to detect malformed messages, such as an Answer message containing a Destination-Host Attribute Value Pair (AVP). The Validator is capable of validating multi-leveled, grouped AVPs, excluding the following content types: * URI, or Identifier types. * Enumerated types against defined values. The Validator is only capable of checking structural integrity, not the content of the message. The Validator performs the following checks: Index:: Checks that the AVPs are in the correct place. For example, `Session-Id` must always be encoded before any other AVP. Multiplicity:: Checks that the message AVPs occur the proper number of times. For example, the Session-ID should only be present once. The `Validator` is called by the stack implementation. It is invoked after the message is received, but before it is dispatched to a remote peer. NOTE: This means that if the peer does not exist in the local peer table, the validator is not called, as the stack fails before calling it. :leveloffset: 1 include::Section-JDiameter-Validator-Configuration.adoc[] :leveloffset: 0 :leveloffset: 1 include::Section-JDiameter-Validator-Source_Overview.adoc[] :leveloffset: 0 ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Setup.adoc~ ================================================ [[_mux_setup]] = Diameter Multiplexer (MUX) Setup [[_mux_preinstall_requirements_and_prerequisites]] == Pre-Install Requirements and Prerequisites Ensure that the following requirements have been met before continuing with the installation process. [[_mux_hardware_requirements]] === Hardware Requirements MUX does not have any hardware requirements. [[_mux_software_prerequisites]] === Software Prerequisites MUX must be deployed either in {jee-version} v4.x or v5.x. However it is possible to adapt configuration files and run in any JMX container. [[_mux_source_code]] == Source Code This section provides instructions on how to obtain and build the {this-platform} Diameter MUX from source code. [[_mux_release_source_building]] === Release Source Code Building . Downloading the source code + IMPORTANT: Subversion is used to manage its source code. Instructions for using Subversion, including installation, can be found at http://svnbook.red-bean.com. + Use SVN to checkout a specific release source. The base URL is {this-trunk-source-code-url} . Then add the specific release version, for example {project-version} . + [source] ---- [usr]$ git clone git@github.com:RestComm/jdiameter.git ---- . Building the source code + IMPORTANT: Maven 3.2.5 (or higher) is used to build the release. Instructions for using Maven2, including installation, can be found at http://maven.apache.org. + Use Maven to build the deployable unit binary. + [source] ---- [usr]$ cd - [usr]$ mvn install ---- + Once the process finishes you should have the SAR built. If the [var]`JBOSS_HOME` environment variable is set, the will be deployed in the container after execution. NOTE: By default {this-platform} Diameter MUX; deploys in the {jee-version} v5.x . To change it, run [app]`maven` with the profile switch command: [parameter]`-Pjboss4`. [[_mux_trunk_source_building]] === Development Trunk Source Building Follow the <<_mux_release_source_building>> procedure, replacing the SVN source code URL with {this-trunk-source-code-url} . ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/Section-MUX-Source_Overview.adoc~ ================================================ [[_mux_source_overview]] = Diameter MUX Source Overview The Diameter MUX capabilities are defined by the `MBean` interface `org.mobicents.diameter.stack.DiameterStackMultiplexerMBean`. This interface defines two types of methods: Management:: Used by &MANAGEMENT.PLATFORM;console. These methods are outside the scope of this documentation. Stack Accessors:: Methods that allow the user to retrieve and use a wrapped stack. The methods below are of interest to a Diameter MUX user: [method]`public Stack getStack();`:: Returns a stack wrapped by the multiplexer. It is present as a convenience method, and the stack should only be changed directly by expert users. [method]`public void registerListener(DiameterListener listener, ApplicationId[] appIds) throws IllegalStateException;`:: Registers a listener to be triggered when a message for a certain application ID is received. [method]`public void unregisterListener(DiameterListener listener);`:: Removes the message listener. [method]`public DiameterStackMultiplexerMBean getMultiplexerMBean();`:: Returns the actual instance of MUX. The listener interface is defined below: [source,java] ---- package org.mobicents.diameter.stack; import java.io.Serializable; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.Request; public interface DiameterListener extends NetworkReqListener, Serializable, EventListener { } ---- MUX can be used as follows: [source,java] ---- public class DiameterActor implements DiameterListener { private ObjectName diameterMultiplexerObjectName = null; private DiameterStackMultiplexerMBean diameterMux = null; private synchronized void initStack() throws Exception { this.diameterMultiplexerObjectName = new ObjectName("diameter.mobicents:service=DiameterStackMultiplexer"); Object[] params = new Object[]{}; String[] signature = new String[]{}; String operation = "getMultiplexerMBean"; this.diameterMux=mbeanServer.invoke(this.diameterMultiplexerObjectName, operation, params, signature); long acctAppIds = new long[]{19312L}; long acctVendorIds = new long[]{193L}; long authAppIds = new long[]{4L}; long authVendorIds = new long[]{0L}; List appIds = new ArrayList(); for(int index = 0;index 1000){ headerSize($scroll); }else{ logoSizeOnSmallScreens(); } if($j(window).width() > 768){ contentMenuPosition(); } contentMenuCheckLastSection(); $j('header:not(.stick_with_left_right_menu) .q_logo a').css('visibility','visible'); /* set header and content menu position and appearance on page load - END */ initFullScreenTemplate(); showHideVerticalMenu(); initMasonryGallery(); initLoadNextPostOnBottom(); }); $j(window).load(function(){ "use strict"; $j('.touch .main_menu li:has(div.second)').doubleTapToGo(); // load script to close menu on touch devices initSmallImageBlogHeight(); setDropDownMenuPosition(); initDropDownMenu(); initPortfolio(); initPortfolioZIndex(); initPortfolioSingleInfo(); initTestimonials(); initVideoBackgroundSize(); initBlog(); initBlogMasonryFullWidth(); initQBlog(); initPortfolioMasonry(); initPortfolioMasonryFilter(); initTabs(); countClientsPerRow(); animatedTextIconHeight(); countAnimatedTextIconPerRow(); initTitleAreaAnimation(); setContentBottomMargin(); footerWidth(); if($j('nav.content_menu').length > 0){ content_menu_position = $j('nav.content_menu').offset().top; contentMenuPosition(); } contentMenuCheckLastSection(); initQodeCarousel(); initPortfolioSlider(); initBlogSlider(); initTabsActiveBorder(); setActiveTabBorder(); initImageHover(); $j('header.stick_with_left_right_menu .q_logo a').css('visibility','visible'); setMargingsForLeftAndRightMenu(); initImageGallerySliderNoSpace(); initVerticalSplitSlider(); initParallax(); //has to be here on last place since some function is interfering with parallax initQodeElementAnimationSkrollr(); setTimeout(function(){ checkAnchorOnScroll(); checkAnchorOnLoad(); // it has to be after content top margin initialization to know where to scroll checkHeaderStyleOnScroll(); //moved to window load because sections are not fully initialized on dom ready and calculations are wrong if($j('.no-touch .carousel').length){skrollr_slider.refresh();} //in order to reload rest of scroll animation on same page after page loads },700); //timeout is set because of some function that interferes with calculating }); $j(window).scroll(function() { "use strict"; $scroll = $j(window).scrollTop(); if($j(window).width() > 1000){ headerSize($scroll); } if($j(window).width() > 768){ contentMenuPosition(); } contentMenuCheckLastSection(); checkVerticalMenuTransparency(); $j('.touch .drop_down > ul > li').mouseleave(); $j('.touch .drop_down > ul > li').blur(); }); $j(window).resize(function() { "use strict"; $window_width = $j(window).width(); $window_height = $j(window).height(); //check paspartu width depending on window size paspartu_width = $window_width < 1024 ? 0.02 : paspartu_width_init; if($j(window).width() > 1000){ headerSize($scroll); }else{ logoSizeOnSmallScreens(); } initMessageHeight(); initTestimonials(); fitAudio(); initSmallImageBlogHeight(); initBlog(); initBlogMasonryFullWidth(); initQBlog(); animatedTextIconHeight(); countAnimatedTextIconPerRow(); initVideoBackgroundSize(); countClientsPerRow(); setContentBottomMargin(); footerWidth(); calculateHeights(); $j('.vertical_split_slider').height($window_height); //used for vertical split slider holder initMasonryGallery(); contentMinHeight(); contentMinHeightWithPaspartu(); }); /* ** Calculating header size on page load and page scroll */ var sticky_animate; function headerSize($scroll){ "use strict"; if(($j('header.page_header').hasClass('scroll_top')) && ($j('header.page_header').hasClass('has_top')) && ($j('header.page_header').hasClass('fixed') || $j('header.page_header').hasClass('fixed_hiding'))){ if($scroll >= 0 && $scroll <= 34){ $j('header.page_header').css('top',-$scroll); $j('header.page_header').css('margin-top',0); $j('.header_top').show(); }else if($scroll > 34){ $j('header.page_header').css('top','-34px'); $j('header.page_header').css('margin-top',34); $j('.header_top').hide(); } } //is scroll amount for sticky set on page? if(typeof page_scroll_amount_for_sticky !== 'undefined') { sticky_amount = page_scroll_amount_for_sticky; } //do we have slider on the page? else if($j('.carousel.full_screen').length) { sticky_amount = $j('.carousel').height(); } //take value from theme options else { sticky_amount = scroll_amount_for_sticky; } if($j('header').hasClass('regular')){ // $j('header .drop_down .second').css('top', header_height + header_bottom_border_weight +'px'); if(header_height - logo_height >= 10){ $j('.q_logo a').height(logo_height); }else{ $j('.q_logo a').height(header_height - 10); } $j('.q_logo a img').css('height','100%'); } if($j('header.page_header').hasClass('fixed')){ if($j('header.page_header').hasClass('scroll_top')){ $top_header_height = 34; }else{ $top_header_height = 0; } if((header_height - $scroll + $top_header_height >= min_header_height_scroll) && ($scroll >= $top_header_height)){ $j('header.page_header').removeClass('scrolled'); $j('header:not(.centered_logo.centered_logo_animate) nav.main_menu > ul > li > a').css('line-height', header_height - $scroll + $top_header_height+'px'); // $j('header .drop_down .second').css('top', header_height + header_bottom_border_weight - ($scroll + $top_header_height)/8+'px'); $j('header:not(.centered_logo.centered_logo_animate) .side_menu_button').css('height', header_height - $scroll + $top_header_height+'px'); $j('header:not(.centered_logo.centered_logo_animate) .shopping_cart_inner').css('height', header_height - $scroll + $top_header_height+'px'); $j('header:not(.centered_logo.centered_logo_animate) .logo_wrapper').css('height', header_height - $scroll + $top_header_height +'px'); if(header_height - logo_height > 0){ $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', logo_height +'px'); }else{ $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', (header_height - $scroll + $top_header_height - 10) +'px'); } }else if($scroll < $top_header_height){ $j('header.page_header').removeClass('scrolled'); $j('header:not(.centered_logo.centered_logo_animate) nav.main_menu > ul > li > a').css('line-height', header_height+'px'); // $j('header .drop_down .second').css('top', header_height + header_bottom_border_weight +'px'); $j('header:not(.centered_logo.centered_logo_animate) .side_menu_button').css('height', header_height+'px'); $j('header:not(.centered_logo.centered_logo_animate) .shopping_cart_inner').css('height', header_height+'px'); $j('header:not(.centered_logo.centered_logo_animate) .logo_wrapper').css('height', header_height+'px'); if(header_height - logo_height > 0){ $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', logo_height +'px'); }else{ $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', (header_height-10)+'px'); } }else if((header_height - $scroll + $top_header_height) < min_header_height_scroll){ $j('header.page_header').addClass('scrolled'); $j('header:not(.centered_logo.centered_logo_animate) nav.main_menu > ul > li > a').css('line-height', min_header_height_scroll+'px'); // $j('header .drop_down .second').css('top', min_header_height_scroll + header_bottom_border_weight +'px'); $j('header:not(.centered_logo.centered_logo_animate) .side_menu_button').css('height', min_header_height_scroll+'px'); $j('header:not(.centered_logo.centered_logo_animate) .shopping_cart_inner').css('height', min_header_height_scroll+'px'); $j('header:not(.centered_logo.centered_logo_animate) .logo_wrapper').css('height', min_header_height_scroll+'px'); if(min_header_height_scroll - logo_height > 0){ $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', logo_height +'px'); }else{ $j('header:not(.centered_logo.centered_logo_animate) .q_logo a').css('height', (min_header_height_scroll-10)+'px'); } } // logo part - start // if($j('header.page_header').hasClass('centered_logo') && $j('header.page_header').hasClass('centered_logo_animate')){ if((header_height - $scroll + $top_header_height < logo_height) && (header_height - $scroll + $top_header_height >= min_header_height_scroll) && (logo_height > min_header_height_scroll - 10) && ($scroll >= $top_header_height)){ $j('.q_logo a').height(header_height - $scroll + $top_header_height - 10); }else if((header_height - $scroll + $top_header_height < logo_height) && (header_height - $scroll + $top_header_height >= min_header_height_scroll) && (logo_height > min_header_height_scroll - 10) && ($scroll < $top_header_height)){ $j('.q_logo a').height(header_height - 10); }else if((header_height - $scroll + $top_header_height < logo_height) && (header_height - $scroll + $top_header_height < min_header_height_scroll) && (logo_height > min_header_height_scroll - 10)){ $j('.q_logo a').height(min_header_height_scroll - 10); }else if((header_height - $scroll + $top_header_height < logo_height) && (header_height - $scroll + $top_header_height < min_header_height_scroll) && (logo_height < min_header_height_scroll - 10)){ $j('.q_logo a').height(logo_height); }else if(($scroll + $top_header_height === 0) && (logo_height > header_height - 10)){ $j('.q_logo a').height(logo_height); }else{ $j('.q_logo a').height(logo_height); } }else if($j('header.page_header').hasClass('centered_logo')) { $j('.q_logo a').height(logo_height); $j('.q_logo img').height('auto'); }else{ $j('.q_logo img').height('100%'); } // logo part - end // } if($j('header.page_header').hasClass('fixed_hiding')){ if($scroll < scroll_amount_for_fixed_hiding){ $j('header.page_header').removeClass('scrolled'); }else{ $j('header.page_header').addClass('scrolled'); } $j('.q_logo a').height(logo_height/2); //because of retina displays $j('.q_logo img').height('100%'); } if($j('header.page_header').hasClass('stick') || $j('header.page_header').hasClass('stick_with_left_right_menu')){ if($scroll > sticky_amount){ if(!$j('header.page_header').hasClass('sticky')){ if($j('header.page_header').hasClass('has_top')){ $top_header_height = 34; }else{ $top_header_height = 0; } var padding_top = $j('header.page_header').hasClass('centered_logo') ? $j('header.page_header').height() : header_height + $top_header_height; if($j('header.page_header').hasClass('menu_bottom')){ padding_top = header_height + 60; //60 is menu height for Sticky Advance header type } $j('header.page_header').addClass('sticky'); $j('.content').css('padding-top',padding_top); window.clearTimeout(sticky_animate); sticky_animate = window.setTimeout(function(){$j('header.page_header').addClass('sticky_animate');},100); if(min_header_height_sticky - logo_height >= 10){ $j('.q_logo a').height(logo_height); }else{ $j('.q_logo a').height(min_header_height_sticky - 10); } if($j('header.page_header').hasClass('menu_bottom')){ initDropDownMenu(); //recalculate dropdown menu position } } // logo part - start // if(min_header_height_sticky - logo_height >= 10){ $j('.q_logo a').height(logo_height); }else{ $j('.q_logo a').height(min_header_height_sticky - 10); } // logo part - end // }else{ if($j('header.page_header').hasClass('sticky')){ $j('header').removeClass('sticky_animate'); $j('header').removeClass('sticky'); $j('.content').css('padding-top','0px'); if($j('header.page_header').hasClass('menu_bottom')){ initDropDownMenu(); //recalculate dropdown menu position } } setMargingsForLeftAndRightMenu(); //need to set margins here since on sticky menu, logo is not visible on left/right logo // logo part - start // if(!$j('header.page_header').hasClass('centered_logo')){ if(header_height - logo_height >= 10){ $j('.q_logo a').height(logo_height); }else{ $j('.q_logo a').height(header_height - 10); } }else{ $j('.q_logo a').height(logo_height); $j('.q_logo img').height('auto'); } $j('.q_logo a img').css('height','100%'); // logo part - end // } } } function setMargingsForLeftAndRightMenu(){ "use strict"; if($j('header.page_header').hasClass('stick_with_left_right_menu') && !$j('header.page_header').hasClass('left_right_margin_set')){ var logo_width = $j('.q_logo a img').width()/2; if($scroll == 0 && logo_width != 0){ $j('header.page_header').addClass('left_right_margin_set'); } $j('.logo_wrapper').width(logo_width*2); $j('nav.main_menu.left_side > ul > li:last-child').css('margin-right',logo_width); $j('nav.main_menu.right_side > ul > li:first-child').css('margin-left',logo_width); $j('.rtl nav.main_menu.left_side > ul > li:first-child').css('margin-right',logo_width); // add for rtl $j('.rtl nav.main_menu.left_side > ul > li:last-child').css('margin-right',0); // add for rtl $j('.rtl nav.main_menu.right_side > ul > li:last-child').css('margin-left',logo_width); // add for rtl $j('.rtl nav.main_menu.right_side > ul > li:first-child').css('margin-left',0); // add for rtl } } /* ** Calculating logo size on smaller screens */ function logoSizeOnSmallScreens(){ "use strict"; // 100 is height of header on small screens if((100 - 20 < logo_height)){ $j('.q_logo a').height(100 - 20); }else{ $j('.q_logo a').height(logo_height); } $j('.q_logo a img').css('height','100%'); $j('header.page_header').removeClass('sticky_animate sticky'); $j('.content').css('padding-top','0px'); } /* ** Calculating minimal height for content */ function contentMinHeight(){ "use strict"; if($j('header .header_bottom').length || $j('header .bottom_header').length){ if($j('header .header_bottom').length){ var headerColorString = $j('header .header_bottom').css('background-color'); } if($j('header .bottom_header').length){ var headerColorString = $j('header .bottom_header').css('background-color'); } var headerTransparency = headerColorString.substring(headerColorString.indexOf('(') + 1, headerColorString.lastIndexOf(')')).split(/,\s*/)[3]; var haeder_add = headerTransparency == undefined && !$j('header.page_header').hasClass('transparent') ? $j('header.page_header').height() : 0; $j('body .content').css('min-height',$window_height - haeder_add - $j('footer:not(.uncover)').height()); } } /* ** Calculating minimal height for content when paspartu is enabled */ function contentMinHeightWithPaspartu(){ "use strict"; if ($j('.paspartu_enabled').length) { var content_height; var paspartu_final_width_px = 0; var paspartu_width_px = $window_width*paspartu_width; var footer_height = $j('footer').height(); if ($j('.disable_footer').length){ footer_height = 0; } if ($j('.vertical_menu_enabled').length){ if ($j('.paspartu_top').length && $j('.paspartu_middle_inner').length){ paspartu_final_width_px += paspartu_width_px; } } else { if ($j('.paspartu_top').length){ paspartu_final_width_px += paspartu_width_px; } } if ($j('.paspartu_bottom').length || !$j('.disable_bottom_paspartu').length){ paspartu_final_width_px += paspartu_width_px; } if ($j('.vertical_menu_enabled').length){ content_height = $window_height - paspartu_final_width_px - footer_height; } else { if($j('header .header_bottom').length){ var headerColorString = $j('header .header_bottom').css('background-color'); } if($j('header .bottom_header').length){ var headerColorString = $j('header .bottom_header').css('background-color'); } var headerTransparency = headerColorString.substring(headerColorString.indexOf('(') + 1, headerColorString.lastIndexOf(')')).split(/,\s*/)[3]; var header_height = headerTransparency == undefined && !$j('header.page_header').hasClass('transparent') ? $j('header.page_header').height() : 0; content_height = $window_height - header_height - paspartu_final_width_px - footer_height; } /*if($j('.content').length){ $j('.content').css('min-height',content_height); }*/ } } /* ** Initialize Qode Slider */ var default_header_style; function initQodeSlider(){ "use strict"; var image_regex = /url\(["']?([^'")]+)['"]?\)/; default_header_style = ""; if($j('header.page_header').hasClass('light')){ default_header_style = 'light';} if($j('header.page_header').hasClass('dark')){ default_header_style = 'dark';} if($j('.carousel').length){ var matrixArray = { zoom_center : '1.2, 0, 0, 1.2, 0, 0', zoom_top_left: '1.2, 0, 0, 1.2, -150, -150', zoom_top_right : '1.2, 0, 0, 1.2, 150, -150', zoom_bottom_left: '1.2, 0, 0, 1.2, -150, 150', zoom_bottom_right: '1.2, 0, 0, 1.2, 150, 150'}; // Function for translating image in slide - START // (function ($) { // // regular expression for parsing out the matrix // components from the matrix string // var matrixRE = /\([0-9epx\.\, \t\-]+/gi; // // parses a matrix string of the form // "matrix(n1,n2,n3,n4,n5,n6)" and // returns an array with the matrix // components // var parseMatrix = function (val) { return val.match(matrixRE)[0].substr(1). split(",").map(function (s) { return parseFloat(s); }); }; // // transform css property names with vendor prefixes; // the plugin will check for values in the order the // names are listed here and return as soon as there // is a value; so listing the W3 std name for the // transform results in that being used if its available // var transformPropNames = [ "transform", "-webkit-transform" ]; var getTransformMatrix = function (el) { // // iterate through the css3 identifiers till we // hit one that yields a value // var matrix = null; transformPropNames.some(function (prop) { matrix = el.css(prop); return (matrix !== null && matrix !== ""); }); // // if "none" then we supplant it with an identity matrix so // that our parsing code below doesn't break // matrix = (!matrix || matrix === "none") ? "matrix(1,0,0,1,0,0)" : matrix; return parseMatrix(matrix); }; // // set the given matrix transform on the element; note that we // apply the css transforms in reverse order of how its given // in "transformPropName" to ensure that the std compliant prop // name shows up last // var setTransformMatrix = function (el, matrix) { var m = "matrix(" + matrix.join(",") + ")"; for (var i = transformPropNames.length - 1; i >= 0; --i) { el.css(transformPropNames[i], m + ' rotate(0.01deg)'); } }; // // interpolates a value between a range given a percent // var interpolate = function (from, to, percent) { return from + ((to - from) * (percent / 100)); }; $.fn.transformAnimate = function (opt) { // // extend the options passed in by caller // var options = { transform: "matrix(1,0,0,1,0,0)" }; $.extend(options, opt); // // initialize our custom property on the element // to track animation progress // this.css("percentAnim", 0); // // supplant "options.step" if it exists with our own // routine // var sourceTransform = getTransformMatrix(this); var targetTransform = parseMatrix(options.transform); options.step = function (percentAnim, fx) { // // compute the interpolated transform matrix for // the current animation progress // var $this = $(this); var matrix = sourceTransform.map(function (c, i) { return interpolate(c, targetTransform[i], percentAnim); }); // // apply the new matrix // setTransformMatrix($this, matrix); // // invoke caller's version of "step" if one // was supplied; // if (opt.step) { opt.step.apply(this, [matrix, fx]); } }; // // animate! // return this.stop().animate({ percentAnim: 100 }, options); }; })(jQuery); // Function for translating image in slide - END // $j('.carousel').each(function(){ var $this = $j(this); var mobile_header; var mobile_header = $j(window).width() < 1000 ? $j('header.page_header').height() : 0; var header_height_add_for_paspartu = $window_width > 1000 && !$j('header.page_header').hasClass('transparent') && $j('body.paspartu_on_top_fixed').length == 0 ? $j('header.page_header').height() : 0; var paspartu_amount_with_top = $j('.paspartu_outer:not(.disable_top_paspartu)').length > 0 ? Math.round($window_width*paspartu_width + header_height_add_for_paspartu) : 0; var paspartu_amount_with_bottom = $j('.paspartu_outer.paspartu_on_bottom_slider').length > 0 ? Math.round($window_width*paspartu_width) : 0; var slider_graphic_coefficient; var slider_title_coefficient; var slider_subtitle_coefficient; var slider_text_coefficient; var slider_button_coefficient; var responsive_breakpoint_set = [1300,1000,768]; if($this.hasClass('advanced_responsiveness')){ responsive_breakpoint_set = [1600,1200,900,650,500,320]; if($this.data('q_responsive_breakpoints')){ if($this.data('q_responsive_breakpoints') == 'set2'){ responsive_breakpoint_set = [1600,1300,1000,768,567,320]; } } var coefficients_graphic_array = $this.data('q_responsive_graphic_coefficients').split(','); var coefficients_title_array = $this.data('q_responsive_title_coefficients').split(','); var coefficients_subtitle_array = $this.data('q_responsive_subtitle_coefficients').split(','); var coefficients_text_array = $this.data('q_responsive_text_coefficients').split(','); var coefficients_button_array = $this.data('q_responsive_button_coefficients').split(','); } //calculate heights for slider holder and slide item, depending on size, but only if slider is set to be responsive and not full screen function setSliderHeight($this, $def_height){ var slider_height = $def_height; if($this.hasClass('advanced_responsiveness')){ //advanced responsiveness if($window_width > responsive_breakpoint_set[0]){ slider_height = $def_height; }else if($window_width > responsive_breakpoint_set[1]){ slider_height = $def_height * 0.75; }else if($window_width > responsive_breakpoint_set[2]){ slider_height = $def_height * 0.6; }else if($window_width > responsive_breakpoint_set[3]){ slider_height = $def_height * 0.55; }else if($window_width <= responsive_breakpoint_set[3]){ slider_height = $def_height * 0.45; } }else{ //old way responsiveness if($window_width > responsive_breakpoint_set[0]){ slider_height = $def_height; }else if($window_width > responsive_breakpoint_set[1]){ slider_height = $def_height * 0.8; }else if($window_width > responsive_breakpoint_set[2]){ slider_height = $def_height * 0.7; }else if($window_width <= responsive_breakpoint_set[2]){ slider_height = $def_height * 1; } } $this.css({'height': (slider_height) + 'px'}); $this.find('.qode_slider_preloader').css({'height': (slider_height) + 'px'}); $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); $this.find('.item').css({'height': (slider_height) + 'px'}); } function resetSliderHeight($def_height){ $this.css({'height': ($def_height) + 'px'}); $this.find('.qode_slider_preloader').css({'height': ($def_height) + 'px'}); $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); $this.find('.item').css({'height': ($def_height) + 'px'}); } function setSliderInitialElementsSize($item,i){ window["slider_graphic_width_" + i] = []; window["slider_graphic_height_" + i] = []; window["slider_svg_width_" + i] = []; window["slider_svg_height_" + i] = []; window["slider_title_" + i] = []; window["slider_subtitle_" + i] = []; window["slider_text_" + i] = []; window["slider_button1_" + i] = []; window["slider_button2_" + i] = []; window["slider_separator_" + i] = []; //graphic size window["slider_graphic_width_" + i].push(parseFloat($item.find('.thumb img').data("width"))); window["slider_graphic_height_" + i].push(parseFloat($item.find('.thumb img').data("height"))); window["slider_svg_width_" + i].push(parseFloat($item.find('.qode_slide-svg-holder svg').attr("width"))); window["slider_svg_height_" + i].push(parseFloat($item.find('.qode_slide-svg-holder svg').attr("height"))); // font-size (0) window["slider_title_" + i].push(parseFloat($item.find('.q_slide_title').css("font-size"))); window["slider_subtitle_" + i].push(parseFloat($item.find('.q_slide_subtitle').css("font-size"))); window["slider_text_" + i].push(parseFloat($item.find('.q_slide_text').css("font-size"))); window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("font-size"))); window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("font-size"))); // line-height (1) window["slider_title_" + i].push(parseFloat($item.find('.q_slide_title').css("line-height"))); window["slider_subtitle_" + i].push(parseFloat($item.find('.q_slide_subtitle').css("line-height"))); window["slider_text_" + i].push(parseFloat($item.find('.q_slide_text').css("line-height"))); window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("line-height"))); window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("line-height"))); // letter-spacing (2) window["slider_title_" + i].push(parseFloat($item.find('.q_slide_title').css("letter-spacing"))); window["slider_subtitle_" + i].push(parseFloat($item.find('.q_slide_subtitle').css("letter-spacing"))); window["slider_text_" + i].push(parseFloat($item.find('.q_slide_text').css("letter-spacing"))); window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("letter-spacing"))); window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("letter-spacing"))); // margin-bottom (3) window["slider_title_" + i].push(parseFloat($item.find('.q_slide_title').css("margin-bottom"))); window["slider_subtitle_" + i].push(parseFloat($item.find('.q_slide_subtitle').css("margin-bottom"))); // slider_button height(3), width(4), padding(5) window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("height"))); window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("height"))); if(parseFloat($item.find('.qbutton:eq(0)').css("width")) != 0){ window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("width"))); }else{ window["slider_button1_" + i].push(0); } if(parseFloat($item.find('.qbutton:eq(1)').css("width")) != 0){ window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("width"))); }else{ window["slider_button2_" + i].push(0); } window["slider_button1_" + i].push(parseFloat($item.find('.qbutton:eq(0)').css("padding-left"))); window["slider_button2_" + i].push(parseFloat($item.find('.qbutton:eq(1)').css("padding-left"))); // margin separator, margin top(0), margin bottom(1) window["slider_separator_" + i].push(parseFloat($item.find('.separator').css("margin-top"))); window["slider_separator_" + i].push(parseFloat($item.find('.separator').css("margin-bottom"))); } //calculate size for slider title, subtitle and text, depending on window size function setSliderElementsSize($item,i){ if($window_width > responsive_breakpoint_set[0]) { slider_graphic_coefficient = coefficients_graphic_array[0]; slider_title_coefficient = coefficients_title_array[0]; slider_subtitle_coefficient = coefficients_subtitle_array[0]; slider_text_coefficient = coefficients_text_array[0]; slider_button_coefficient = coefficients_button_array[0]; }else if($window_width > responsive_breakpoint_set[1]){ slider_graphic_coefficient = coefficients_graphic_array[1]; slider_title_coefficient = coefficients_title_array[1]; slider_subtitle_coefficient = coefficients_subtitle_array[1]; slider_text_coefficient = coefficients_text_array[1]; slider_button_coefficient = coefficients_button_array[1]; }else if($window_width > responsive_breakpoint_set[2]){ slider_graphic_coefficient = coefficients_graphic_array[2]; slider_title_coefficient = coefficients_title_array[2]; slider_subtitle_coefficient = coefficients_subtitle_array[2]; slider_text_coefficient = coefficients_text_array[2]; slider_button_coefficient = coefficients_button_array[2]; }else if($window_width > responsive_breakpoint_set[3]){ slider_graphic_coefficient = coefficients_graphic_array[3]; slider_title_coefficient = coefficients_title_array[3]; slider_subtitle_coefficient = coefficients_subtitle_array[3]; slider_text_coefficient = coefficients_text_array[3]; slider_button_coefficient = coefficients_button_array[3]; }else if ($window_width > responsive_breakpoint_set[4]) { slider_graphic_coefficient = coefficients_graphic_array[4]; slider_title_coefficient = coefficients_title_array[4]; slider_subtitle_coefficient = coefficients_subtitle_array[4]; slider_text_coefficient = coefficients_text_array[4]; slider_button_coefficient = coefficients_button_array[4]; }else if ($window_width > responsive_breakpoint_set[5]){ slider_graphic_coefficient = coefficients_graphic_array[5]; slider_title_coefficient = coefficients_title_array[5]; slider_subtitle_coefficient = coefficients_subtitle_array[5]; slider_text_coefficient = coefficients_text_array[5]; slider_button_coefficient = coefficients_button_array[5]; } else{ slider_graphic_coefficient = coefficients_graphic_array[6]; slider_title_coefficient = coefficients_title_array[6]; slider_subtitle_coefficient = coefficients_subtitle_array[6]; slider_text_coefficient = coefficients_text_array[6]; slider_button_coefficient = coefficients_button_array[6]; } // letter-spacing decrease quicker var slider_title_coefficient_letter_spacing = slider_title_coefficient; var slider_subtitle_coefficient_letter_spacing = slider_subtitle_coefficient; var slider_text_coefficient_letter_spacing = slider_text_coefficient; if($window_width <= responsive_breakpoint_set[0]) { slider_title_coefficient_letter_spacing = slider_title_coefficient/2; slider_subtitle_coefficient_letter_spacing = slider_subtitle_coefficient/2; slider_text_coefficient_letter_spacing = slider_text_coefficient/2; } $item.find('.thumb').css({"width": Math.round(window["slider_graphic_width_" + i][0]*slider_graphic_coefficient) + 'px'}).css({"height": Math.round(window["slider_graphic_height_" + i][0]*slider_graphic_coefficient) + 'px'}); $item.find('.qode_slide-svg-holder svg').css({"width": Math.round(window["slider_svg_width_" + i][0]*slider_graphic_coefficient) + 'px'}).css({"height": Math.round(window["slider_svg_height_" + i][0]*slider_graphic_coefficient) + 'px'}); $item.find('.q_slide_title').css({"font-size": Math.round(window["slider_title_" + i][0]*slider_title_coefficient) + 'px'}); $item.find('.q_slide_title').css({"line-height": Math.round(window["slider_title_" + i][1]*slider_title_coefficient) + 'px'}); $item.find('.q_slide_title').css({"letter-spacing": Math.round(window["slider_title_" + i][2]*slider_title_coefficient_letter_spacing) + 'px'}); $item.find('.q_slide_title').css({"margin-bottom": Math.round(window["slider_title_" + i][3]*slider_title_coefficient) + 'px'}); $item.find('.q_slide_subtitle').css({"font-size": Math.round(window["slider_subtitle_" + i][0]*slider_subtitle_coefficient) + 'px'}); $item.find('.q_slide_subtitle').css({"line-height": Math.round(window["slider_subtitle_" + i][1]*slider_subtitle_coefficient) + 'px'}); $item.find('.q_slide_subtitle').css({"letter-spacing": Math.round(window["slider_subtitle_" + i][2]*slider_subtitle_coefficient_letter_spacing) + 'px'}); $item.find('.q_slide_subtitle').css({"margin-bottom": Math.round(window["slider_subtitle_" + i][3]*slider_subtitle_coefficient) + 'px'}); $item.find('.q_slide_text').css({"font-size": Math.round(window["slider_text_" + i][0]*slider_text_coefficient) + 'px'}); $item.find('.q_slide_text').css({"line-height": Math.round(window["slider_text_" + i][1]*slider_text_coefficient) + 'px'}); $item.find('.q_slide_text').css({"letter-spacing": Math.round(window["slider_text_" + i][2]*slider_text_coefficient_letter_spacing) + 'px'}); $item.find('.qbutton:eq(0)').css({"font-size": Math.round(window["slider_button1_" + i][0]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(1)').css({"font-size": Math.round(window["slider_button2_" + i][0]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(0)').css({"line-height": Math.round(window["slider_button1_" + i][1]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(1)').css({"line-height": Math.round(window["slider_button2_" + i][1]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(0)').css({"letter-spacing": Math.round(window["slider_button1_" + i][2]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(1)').css({"letter-spacing": Math.round(window["slider_button2_" + i][2]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(0)').css({"height": Math.round(window["slider_button1_" + i][3]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(1)').css({"height": Math.round(window["slider_button2_" + i][3]*slider_button_coefficient) + 'px'}); if(window["slider_button1_" + i][4] != 0) { $item.find('.qbutton:eq(0)').css({"width": Math.round(window["slider_button1_" + i][4]*slider_button_coefficient) + 'px'}); }else{ $item.find('.qbutton:eq(0)').css({"width": 'auto'}); } if(window["slider_button2_" + i][4] != 0) { $item.find('.qbutton:eq(1)').css({"width": Math.round(window["slider_button2_" + i][4]*slider_button_coefficient) + 'px'}); }else{ $item.find('.qbutton:eq(1)').css({"width": 'auto'}); } $item.find('.qbutton:eq(0)').css({"padding-left": Math.round(window["slider_button1_" + i][5]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(1)').css({"padding-left": Math.round(window["slider_button2_" + i][5]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(0)').css({"padding-right": Math.round(window["slider_button1_" + i][5]*slider_button_coefficient) + 'px'}); $item.find('.qbutton:eq(1)').css({"padding-right": Math.round(window["slider_button2_" + i][5]*slider_button_coefficient) + 'px'}); $item.find('.separator').css({"margin-top": Math.round(window["slider_separator_" + i][0]*slider_title_coefficient) + 'px'}); $item.find('.separator').css({"margin-bottom": Math.round(window["slider_separator_" + i][1]*slider_title_coefficient) + 'px'}); } function resetSliderElementsSize($item,i){ $item.find('.thumb').css({"width": Math.round(window["slider_graphic_width_" + i][0]) + 'px'}).css({"height": Math.round(window["slider_graphic_height_" + i][0]) + 'px'}); $item.find('.qode_slide-svg-holder svg').css({"width": Math.round(window["slider_svg_width_" + i][0]) + 'px'}).css({"height": Math.round(window["slider_svg_height_" + i][0]) + 'px'}); $item.find('.q_slide_title').css({"font-size": Math.round(window["slider_title_" + i][0]) + 'px'}); $item.find('.q_slide_title').css({"line-height": Math.round(window["slider_title_" + i][1]) + 'px'}); $item.find('.q_slide_title').css({"letter-spacing": Math.round(window["slider_title_" + i][2]) + 'px'}); $item.find('.q_slide_title').css({"margin-bottom": Math.round(window["slider_title_" + i][3]) + 'px'}); $item.find('.q_slide_subtitle').css({"font-size": Math.round(window["slider_subtitle_" + i][0]) + 'px'}); $item.find('.q_slide_subtitle').css({"line-height": Math.round(window["slider_subtitle_" + i][1]) + 'px'}); $item.find('.q_slide_subtitle').css({"letter-spacing": Math.round(window["slider_subtitle_" + i][2]) + 'px'}); $item.find('.q_slide_subtitle').css({"margin-bottom": Math.round(window["slider_subtitle_" + i][3]) + 'px'}); $item.find('.q_slide_text').css({"font-size": Math.round(window["slider_text_" + i][0]) + 'px'}); $item.find('.q_slide_text').css({"line-height": Math.round(window["slider_text_" + i][1]) + 'px'}); $item.find('.q_slide_text').css({"letter-spacing": Math.round(window["slider_text_" + i][2]) + 'px'}); $item.find('.qbutton:eq(0)').css({"font-size": Math.round(window["slider_button1_" + i][0]) + 'px'}); $item.find('.qbutton:eq(1)').css({"font-size": Math.round(window["slider_button2_" + i][0]) + 'px'}); $item.find('.qbutton:eq(0)').css({"line-height": Math.round(window["slider_button1_" + i][1]) + 'px'}); $item.find('.qbutton:eq(1)').css({"line-height": Math.round(window["slider_button2_" + i][1]) + 'px'}); $item.find('.qbutton:eq(0)').css({"letter-spacing": Math.round(window["slider_button1_" + i][2]) + 'px'}); $item.find('.qbutton:eq(1)').css({"letter-spacing": Math.round(window["slider_button2_" + i][2]) + 'px'}); $item.find('.qbutton:eq(0)').css({"height": Math.round(window["slider_button1_" + i][3]) + 'px'}); $item.find('.qbutton:eq(1)').css({"height": Math.round(window["slider_button2_" + i][3]) + 'px'}); if(window["slider_button1_" + i][4] != 0) { $item.find('.qbutton:eq(0)').css({"width": Math.round(window["slider_button1_" + i][4]) + 'px'}); }else{ $item.find('.qbutton:eq(0)').css({"width": 'auto'}); } if(window["slider_button2_" + i][4] != 0) { $item.find('.qbutton:eq(1)').css({"width": Math.round(window["slider_button2_" + i][4]) + 'px'}); }else{ $item.find('.qbutton:eq(1)').css({"width": 'auto'}); } $item.find('.qbutton:eq(0)').css({"padding-left": Math.round(window["slider_button1_" + i][5]) + 'px'}); $item.find('.qbutton:eq(1)').css({"padding-left": Math.round(window["slider_button2_" + i][5]) + 'px'}); $item.find('.qbutton:eq(0)').css({"padding-right": Math.round(window["slider_button1_" + i][5]) + 'px'}); $item.find('.qbutton:eq(1)').css({"padding-right": Math.round(window["slider_button2_" + i][5]) + 'px'}); $item.find('.separator').css({"margin-top": Math.round(window["slider_separator_" + i][0]) + 'px'}); $item.find('.separator').css({"margin-bottom": Math.round(window["slider_separator_" + i][1]) + 'px'}); } if($this.hasClass('full_screen')){ $this.css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); $this.find('.qode_slider_preloader').css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); $this.find('.item').css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ if(!$j('body').hasClass('paspartu_on_top_fixed')){ $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); } } if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); } $j(window).resize(function() { mobile_header = $j(window).width() < 1000 ? $j('header.page_header').height() : 0; header_height_add_for_paspartu = $window_width > 1000 && !$j('header.page_header').hasClass('transparent') && $j('body.paspartu_on_top_fixed').length == 0 ? $j('header.page_header').height() : 0; paspartu_amount_with_top = $j('.paspartu_outer:not(.disable_top_paspartu)').length > 0 ? Math.round($window_width*paspartu_width + header_height_add_for_paspartu) : 0; paspartu_amount_with_bottom = $j('.paspartu_outer.paspartu_on_bottom_slider').length > 0 ? Math.round($window_width*paspartu_width) : 0; $this.css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); $this.find('.item').css({'height': ($j(window).height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px'}); if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ if(!$j('body').hasClass('paspartu_on_top_fixed')){ $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); } } if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); } if($this.hasClass('advanced_responsiveness')){ $this.find('.item').each(function(i){ setSliderElementsSize($j(this),i); }); } }); }else if($this.hasClass('responsive_height')){ var $def_height = $this.data('height'); $this.find('.qode_slider_preloader').css({'height': ($this.height() - mobile_header - paspartu_amount_with_top - paspartu_amount_with_bottom) + 'px', 'display': 'block'}); if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ if(!$j('body').hasClass('paspartu_on_top_fixed')){ $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); } } if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); } setSliderHeight($this, $def_height); $j(window).resize(function() { if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ header_height_add_for_paspartu = $window_width > 1000 && !$j('header.page_header').hasClass('transparent') ? $j('header.page_header').height() : 0; if(!$j('body').hasClass('paspartu_on_top_fixed')){ $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); } } if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); } setSliderHeight($this, $def_height); if($this.hasClass('advanced_responsiveness')){ $this.find('.item').each(function(i){ setSliderElementsSize($j(this),i); }); } }); }else { $this.find('.qode_slider_preloader').css({'height': ($this.height() - mobile_header) + 'px', 'display': 'block'}); $this.find('.qode_slider_preloader .ajax_loader').css({'display': 'block'}); if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ if(!$j('body').hasClass('paspartu_on_top_fixed')){ $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); } } if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); } if($this.hasClass('advanced_responsiveness')){ $this.find('.item').each(function(i){ setSliderInitialElementsSize($j(this),i); setSliderElementsSize($j(this),i); }); } $window_width < 1000 ? setSliderHeight($this, $def_height) : resetSliderHeight($def_height); $j(window).resize(function() { if($j('.paspartu_outer:not(.disable_top_paspartu)').length){ header_height_add_for_paspartu = $window_width > 1000 && !$j('header.page_header').hasClass('transparent') ? $j('header.page_header').height() : 0; if(!$j('body').hasClass('paspartu_on_top_fixed')){ $this.closest('.q_slider').css('padding-top', Math.round(header_height_add_for_paspartu + $window_width * paspartu_width)); } } if($j('.paspartu_outer.paspartu_on_bottom_slider').length){ $this.closest('.q_slider').css('padding-bottom', Math.round($window_width * paspartu_width)); } if($window_width < 1000){ setSliderHeight($this, $def_height); if($this.hasClass('advanced_responsiveness')){ $this.find('.item').each(function(i){ setSliderElementsSize($j(this),i); }); } }else{ resetSliderHeight($def_height); if($this.hasClass('advanced_responsiveness')){ $this.find('.item').each(function(i){ resetSliderElementsSize($j(this),i); }); } } }); } if($j('body:not(.boxed):not(.vertical_menu_transparency):not(.vertical_menu_hidden):not(.page-template-landing_page-php)').hasClass('vertical_menu_enabled') && $j(window).width() > 1000){ var paspartu_add = $j('body').hasClass('paspartu_enabled') ? 2*Math.round($window_width*paspartu_width) : 0; //2 times paspartu (left and right side) $this.find('.carousel-inner').width($window_width - 260 - paspartu_add); $j(window).resize(function() { if($j(window).width() > 1000){ paspartu_add = $j('body').hasClass('paspartu_enabled') ? 2*Math.round($window_width*paspartu_width) : 0; //2 times paspartu (left and right side) $this.find('.carousel-inner').width($window_width - 260 - paspartu_add); } else { $this.find('.carousel-inner').css('width','100%'); } }); } if($j('body:not(.boxed):not(.vertical_menu_transparency):not(.page-template-landing_page-php)').hasClass('vertical_menu_hidden') && $window_width > 1000){ var paspartu_add = $j('body').hasClass('paspartu_enabled') ? 2*Math.round($window_width*paspartu_width) : 0; //2 times paspartu (left and right side) $this.find('.carousel-inner').width($window_width - 40 - paspartu_add); $j(window).resize(function() { if($j(window).width() > 1000){ paspartu_add = $j('body').hasClass('paspartu_enabled') ? 2*Math.round($window_width*paspartu_width) : 0; //2 times paspartu (left and right side) $this.find('.carousel-inner').width($window_width - 40 - paspartu_add); } else { $this.find('.carousel-inner').css('width','100%'); } }); } $j(window).scroll(function() { if($scroll > ($this.height()+$j('header.page_header').height()) && $j(window).width() > 1000){ $this.find('.carousel-inner, .carousel-indicators, button').hide(); }else{ $this.find('.carousel-inner, .carousel-indicators, button').show(); } }); var $slide_animation = $this.data('slide_animation'); if($slide_animation === ""){ $slide_animation = 6000; } // function for setting prev/next numbers on arrows var all_items_count = $j('div.item').length; function setPrevNextNumbers(curr_item, all_items_count){ if(curr_item == 1){ $this.find('.left.carousel-control .prev').html(all_items_count); $this.find('.right.carousel-control .next').html(curr_item + 1); }else if(curr_item == all_items_count){ $this.find('.left.carousel-control .prev').html(curr_item - 1); $this.find('.right.carousel-control .next').html(1); }else{ $this.find('.left.carousel-control .prev').html(curr_item - 1); $this.find('.right.carousel-control .next').html(curr_item + 1); } } function initSlider(){ //set active class on first item $this.find('.carousel-inner .item:first-child').addClass('active'); checkSliderForHeaderStyle($j('.carousel .active'), $this.hasClass('header_effect')); if($this.hasClass('slider_thumbs')){ // initial state of prev/next numbers setPrevNextNumbers(1, all_items_count); //set prev and next thumb on load if($this.find('.active').next('div').find('.image').length){ src = image_regex.exec($this.find('.active').next('div').find('.image').attr('style')); next_image = new Image(); next_image.src = src[1]; }else{ next_image = $this.find('.active').next('div').find('> .video').clone(); next_image.find('.video-overlay').remove(); next_image.find('.video-wrap').width(170).height(95); next_image.find('.mejs-container').width(170).height(95); next_image.find('video').width(170).height(95); } $this.find('.right.carousel-control .img').html(next_image).find('img, div.video').addClass('old'); if($this.find('.carousel-inner .item:last-child .image').length){ src = image_regex.exec($this.find('.carousel-inner .item:last-child .image').attr('style')); prev_image = new Image(); prev_image.src = src[1]; }else{ prev_image = $this.find('.carousel-inner .item:last-child > .video').clone(); prev_image.find('.video-overlay').remove(); prev_image.find('.video-wrap').width(170).height(95); prev_image.find('.mejs-container').width(170).height(95); prev_image.find('video').width(170).height(95); } $this.find('.left.carousel-control .img').html(prev_image).find('img, div.video').addClass('old'); } if($this.hasClass('q_auto_start')){ $this.carousel({ interval: $slide_animation, pause: false }); } else { $this.carousel({ interval: 0, pause: false }); } if($this.find('.item video').length){ initVideoBackgroundSize(); } if($this.hasClass('advanced_responsiveness') && ($this.hasClass('responsive_height') || $this.hasClass('full_screen'))){ $this.find('.item').each(function (i) { setSliderInitialElementsSize($j(this), i); setSliderElementsSize($j(this), i); }); } //initiate image animation if($j('.carousel-inner .item:first-child').hasClass('animate_image') && $window_width > 1000){ $this.find('.carousel-inner .item.animate_image:first-child .image').transformAnimate({ transform: "matrix("+matrixArray[$j('.carousel-inner .item:first-child').data('animate_image')]+")", duration: 30000 }); } } if($j('html').hasClass('touch')){ if($this.find('.item:first-child .mobile-video-image').length > 0){ src = image_regex.exec($this.find('.item:first-child .mobile-video-image').attr('style')); if (src) { var backImg = new Image(); backImg.src = src[1]; $j(backImg).load(function(){ $j('.qode_slider_preloader').fadeOut(500); initSlider(); checkSVG($this); }); } } else{ src = image_regex.exec($this.find('.item:first-child .image').attr('style')); if (src) { var backImg = new Image(); backImg.src = src[1]; $j(backImg).load(function(){ $j('.qode_slider_preloader').fadeOut(500); initSlider(); checkSVG($this); }); } } } else { if($this.find('.item:first-child video').length > 0){ $this.find('.item:first-child video').get(0).addEventListener('loadeddata',function(){ $j('.qode_slider_preloader').fadeOut(500); initSlider(); checkSVG($this); }); }else{ src = image_regex.exec($this.find('.item:first-child .image').attr('style')); if (src) { var backImg = new Image(); backImg.src = src[1]; $j(backImg).load(function(){ $j('.qode_slider_preloader').fadeOut(500); initSlider(); checkSVG($this); }); } } } $this.on('slide.bs.carousel', function () { $this.addClass('in_progress'); $this.find('.active .slider_content_outer').fadeTo(800,0); }); $this.on('slid.bs.carousel', function () { $this.removeClass('in_progress'); $this.find('.active .slider_content_outer').fadeTo(0,1); checkSVG($this); // initiate image animation on active slide and reset all others $j('div.item.animate_image .image').stop().css({'transform':'', '-webkit-transform':''}); if($j('div.item.active').hasClass('animate_image') && $window_width > 1000){ $j('div.item.animate_image.active .image').transformAnimate({ transform: "matrix("+matrixArray[$j('div.item.animate_image.active').data('animate_image')]+")", duration: 30000 }); } if($this.hasClass('slider_thumbs')){ var curr_item = $j('div.item').index($j('div.item.active')[0]) + 1; setPrevNextNumbers(curr_item, all_items_count); // prev thumb if($this.find('.active').prev('div.item').length){ if($this.find('.active').prev('div').find('.image').length){ src = image_regex.exec($this.find('.active').prev('div').find('.image').attr('style')); prev_image = new Image(); prev_image.src = src[1]; }else{ prev_image = $this.find('.active').prev('div').find('> .video').clone(); prev_image.find('.video-overlay').remove(); prev_image.find('.video-wrap').width(170).height(95); prev_image.find('.mejs-container').width(170).height(95); prev_image.find('video').width(170).height(95); } $this.find('.left.carousel-control .img .old').fadeOut(300,function(){ $j(this).remove(); }); $this.find('.left.carousel-control .img').append(prev_image).find('img, div.video').fadeIn(300).addClass('old'); }else{ if($this.find('.carousel-inner .item:last-child .image').length){ src = image_regex.exec($this.find('.carousel-inner .item:last-child .image').attr('style')); prev_image = new Image(); prev_image.src = src[1]; }else{ prev_image = $this.find('.carousel-inner .item:last-child > .video').clone(); prev_image.find('.video-overlay').remove(); prev_image.find('.video-wrap').width(170).height(95); prev_image.find('.mejs-container').width(170).height(95); prev_image.find('video').width(170).height(95); } $this.find('.left.carousel-control .img .old').fadeOut(300,function(){ $j(this).remove(); }); $this.find('.left.carousel-control .img').append(prev_image).find('img, div.video').fadeIn(300).addClass('old'); } // next thumb if($this.find('.active').next('div.item').length){ if($this.find('.active').next('div').find('.image').length){ src = image_regex.exec($this.find('.active').next('div').find('.image').attr('style')); next_image = new Image(); next_image.src = src[1]; }else{ next_image = $this.find('.active').next('div').find('> .video').clone(); next_image.find('.video-overlay').remove(); next_image.find('.video-wrap').width(170).height(95); next_image.find('.mejs-container').width(170).height(95); next_image.find('video').width(170).height(95); } $this.find('.right.carousel-control .img .old').fadeOut(300,function(){ $j(this).remove(); }); $this.find('.right.carousel-control .img').append(next_image).find('img, div.video').fadeIn(300).addClass('old'); }else{ if($this.find('.carousel-inner .item:first-child .image').length){ src = image_regex.exec($this.find('.carousel-inner .item:first-child .image').attr('style')); next_image = new Image(); next_image.src = src[1]; }else{ next_image = $this.find('.carousel-inner .item:first-child > .video').clone(); next_image.find('.video-overlay').remove(); next_image.find('.video-wrap').width(170).height(95); next_image.find('.mejs-container').width(170).height(95); next_image.find('video').width(170).height(95); } $this.find('.right.carousel-control .img .old').fadeOut(300,function(){ $j(this).remove(); }); $this.find('.right.carousel-control .img').append(next_image).find('img, div.video').fadeIn(300).addClass('old'); } } }); $this.swipe( { swipeLeft: function(event, direction, distance, duration, fingerCount){ $this.carousel('next'); }, swipeRight: function(event, direction, distance, duration, fingerCount){ $this.carousel('prev'); }, threshold:20 }); }); if ($j('.no-touch .carousel').length) { skrollr_slider = skrollr.init({ edgeStrategy: 'set', smoothScrolling: true, forceHeight: false }); skrollr_slider.refresh(); } } } function checkSliderForHeaderStyle($this, header_effect){ "use strict"; var slide_header_style = ""; var navigation_color = $this.data('navigation-color'); if($this.hasClass('light')){ slide_header_style = 'light';} if($this.hasClass('dark')){ slide_header_style = 'dark';} if( slide_header_style !== ""){ if(header_effect){ $j('header.page_header').removeClass('dark light').addClass(slide_header_style); $j('aside.vertical_menu_area').removeClass('dark light').addClass(slide_header_style); } $j('.carousel .carousel-control, .carousel .carousel-indicators').removeClass('dark light').addClass(slide_header_style); }else{ if(header_effect){ $j('header.page_header').removeClass('dark light').addClass(default_header_style); $j('aside.vertical_menu_area').removeClass('dark light').addClass(default_header_style); } $j('.carousel .carousel-control, .carousel .carousel-indicators').removeClass('dark light').addClass(default_header_style); } if(navigation_color !== undefined){ $j('.carousel-control .thumb_holder .thumb_top, .carousel-indicators li').css('background-color',navigation_color); $j('.carousel-control .prev_nav, .carousel-control .next_nav').css('border-color',navigation_color); $j('.carousel-control .prev_nav i, .carousel-control .next_nav i').css('color',navigation_color); }else{ $j('.carousel-control .thumb_holder .thumb_top, .carousel-indicators li').css('background-color',''); $j('.carousel-control .prev_nav, .carousel-control .next_nav').css('border-color',''); $j('.carousel-control .prev_nav i, .carousel-control .next_nav i').css('color',''); } } /* ** Set heights for qode carousel, portfolio slider and blog slider */ function calculateHeights(){ if($j('.portfolio_slides').length){ $j('.portfolio_slides').each(function(){ $j(this).parents('.caroufredsel_wrapper').css({'height' : ($j(this).find('li.item').outerHeight()-3) + 'px'}); //3 is because of the white line bellow the slider }); } if($j('.qode_carousels .slides').length){ $j('.qode_carousels .slides').each(function(){ $j(this).parents('.caroufredsel_wrapper').css({'height' : ($j(this).find('li.item').outerHeight()) + 'px'}); }); } if($j('.blog_slides').length){ $j('.blog_slides').each(function(){ $j(this).parents('.caroufredsel_wrapper').css({'height' : ($j(this).find('li.item').outerHeight()-3) + 'px'}); }); } } /* ** Init Qode Carousel */ function initQodeCarousel(){ "use strict"; if($j('.qode_carousels').length){ $j('.qode_carousels').each(function(){ var itemWidth = ($j(this).parents('.grid_section').length == 1) ? 170 : 315; $j(this).find('.slides').carouFredSel({ circular: true, responsive: true, scroll : { items : 1, duration : 1000, pauseOnHover : false }, items: { width: itemWidth, visible: { min: 1, max: 6 } }, auto: true, mousewheel: false, swipe: { onMouse: true, onTouch: true } }).animate({'opacity': 1},1000); }); calculateHeights(); } } /* ** Init Portfolio Slider */ function initPortfolioSlider(){ "use strict"; if($j('.portfolio_slider').length){ $j('.portfolio_slider').each(function(){ var number_of_items; var item_width_fw; if(typeof $j(this).data('number_of_items') !== 'undefined') { number_of_items = $j(this).data('number_of_items'); } else { number_of_items = 'auto'; } switch(number_of_items){ case 4: item_width_fw = 500; break; case 5: item_width_fw = 350; break; default: item_width_fw = 500; break; } var maxItems = ($j(this).parents('.grid_section').length == 1) ? 3 : number_of_items; var itemWidth = ($j(this).parents('.grid_section').length == 1) ? 353 : item_width_fw; $j(this).find('.portfolio_slides').carouFredSel({ circular: true, responsive: true, scroll: 1, prev : { button : function() { return $j(this).parent().siblings('.caroufredsel-direction-nav').find('#caroufredsel-prev'); } }, next : { button : function() { return $j(this).parent().siblings('.caroufredsel-direction-nav').find('#caroufredsel-next'); } }, items: { width: itemWidth, visible: { min: 1, max: maxItems } }, auto: false, mousewheel: false, swipe: { onMouse: true, onTouch: true } }).animate({'opacity': 1},1000); }); calculateHeights(); $j('.portfolio_slider .flex-direction-nav a').click(function(e){ e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); }); } } /* ** Init Blog Slider */ function initBlogSlider(){ "use strict"; if($j('.blog_slider').length){ $j('.blog_slider').each(function(){ var blogs_shown; var maxItems; var itemWidth; var autoPlay = false; if(typeof $j(this).data('blogs_shown') !== 'undefined') { blogs_shown = $j(this).data('blogs_shown'); } else if($j(this).hasClass('simple_slider')){ blogs_shown = 1; } else{ blogs_shown = 'auto'; } if ($j(this).hasClass('simple_slider')) { maxItems = 1; itemWidth = 300; autoPlay = false; } else { maxItems = ($j(this).parents('.grid_section').length == 1) ? 3 : blogs_shown; var itemWidthTemp; switch (blogs_shown) { case 3: itemWidthTemp = 667; break; case 4: itemWidthTemp = 500; break; case 5: itemWidthTemp = 400; break; case 6: itemWidthTemp = 334; break; default: itemWidthTemp = 500; break; } itemWidth = ($j(this).parents('.grid_section').length == 1) ? 353 : itemWidthTemp; } $j(this).find('.blog_slides').carouFredSel({ circular: true, responsive: true, scroll: 1, prev : { button : function() { return $j(this).parent().siblings('.caroufredsel-direction-nav').find('#caroufredsel-prev'); } }, next : { button : function() { return $j(this).parent().siblings('.caroufredsel-direction-nav').find('#caroufredsel-next'); } }, items: { width: itemWidth, visible: { min: 1, max: maxItems } }, auto: autoPlay, mousewheel: false, swipe: { onMouse: true, onTouch: true } }).animate({'opacity': 1},1000); }); calculateHeights(); $j('.blog_slider .flex-direction-nav a').click(function(e){ e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); }); } } /* ** Opening side menu on "menu button" click */ var current_scroll; function initSideMenu(){ "use strict"; if ($j('body').hasClass('side_area_uncovered_from_content')) { $j('.side_menu_button_wrapper a.side_menu_button_link, a.close_side_menu').click(function(e){ e.preventDefault(); $j('.side_menu').css({'right':'0'}); if(!$j('.side_menu_button_wrapper a.side_menu_button_link').hasClass('opened')){ $j('.side_menu').css({'visibility':'visible'}); $j(this).addClass('opened'); $j('body').addClass('right_side_menu_opened'); current_scroll = $j(window).scrollTop(); $j(window).scroll(function() { if(Math.abs($scroll - current_scroll) > 400){ $j('body').removeClass('right_side_menu_opened'); $j('.side_menu_button_wrapper a').removeClass('opened'); var hide_side_menu = setTimeout(function(){ $j('.side_menu').css({'visibility':'hidden'}); clearTimeout(hide_side_menu); },400); } }); }else{ $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); $j('body').removeClass('right_side_menu_opened'); var hide_side_menu = setTimeout(function(){ $j('.side_menu').css({'visibility':'hidden'}); clearTimeout(hide_side_menu); },400); } }); } if ($j('body').hasClass('side_menu_slide_with_content')) { $j('.side_menu_button_wrapper a.side_menu_button_link, a.close_side_menu').click(function(e){ e.preventDefault(); if(!$j('.side_menu_button_wrapper a.side_menu_button_link').hasClass('opened')){ $j(this).addClass('opened'); $j('body').addClass('side_menu_open'); current_scroll = $j(window).scrollTop(); $j(window).scroll(function() { if(Math.abs($scroll - current_scroll) > 400){ $j('body').removeClass('side_menu_open'); $j('.side_menu_button_wrapper a').removeClass('opened'); } }); }else{//hamburger icon has class open on its click $j('body').removeClass('side_menu_open'); $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); $j('body').removeClass('side_menu_open'); } e.stopPropagation(); $j('.wrapper').click(function() { e.preventDefault(); $j('body').removeClass('side_menu_open'); $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); $j('body').removeClass('side_menu_open'); }); }); } if ($j('body').hasClass('side_menu_slide_from_right')) { $j('.wrapper').prepend('
'); $j('.side_menu_button_wrapper a.side_menu_button_link, a.close_side_menu').click(function(e){ e.preventDefault(); if(!$j('.side_menu_button_wrapper a.side_menu_button_link').hasClass('opened')){ $j(this).addClass('opened'); $j('body').addClass('right_side_menu_opened'); $j(' .wrapper .cover').click(function() { $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); $j('body').removeClass('right_side_menu_opened'); $j('.side_menu_button_wrapper a').removeClass('opened'); }); current_scroll = $j(window).scrollTop(); $j(window).scroll(function() { if(Math.abs($scroll - current_scroll) > 400){ $j('body').removeClass('right_side_menu_opened'); $j('.side_menu_button_wrapper a').removeClass('opened'); } }); }else{ $j('.side_menu_button_wrapper a.side_menu_button_link').removeClass('opened'); $j('body').removeClass('right_side_menu_opened'); } }); } } function setDropDownMenuPosition(){ "use strict"; var menu_items = $j(".drop_down > ul > li.narrow"); menu_items.each( function(i) { var browser_width = $j(window).width()-16; // 16 is width of scroll bar var boxed_layout = 1150; // boxed layout width var menu_item_position = $j(menu_items[i]).offset().left; var sub_menu_width = $j(menu_items[i]).find('.second .inner ul').width(); var menu_item_from_left = 0; if($j('body').hasClass('boxed')){ menu_item_from_left = boxed_layout - (menu_item_position - (browser_width - boxed_layout)/2) + 17; // 17 is right padding between menu elements } else { menu_item_from_left = browser_width - menu_item_position + 17; // 17 is right padding between menu elements } var sub_menu_from_left; if($j(menu_items[i]).find('li.sub').length > 0){ sub_menu_from_left = menu_item_from_left - sub_menu_width; } if(menu_item_from_left < sub_menu_width || sub_menu_from_left < sub_menu_width){ $j(menu_items[i]).find('.second').addClass('right'); $j(menu_items[i]).find('.second .inner ul').addClass('right'); } }); } function initDropDownMenu(){ "use strict"; var menu_items = $j('.drop_down > ul > li'); menu_items.each( function(i) { if ($j(menu_items[i]).find('.second').length > 0) { if($j(menu_items[i]).hasClass('wide')){ var dropdown = $j(this).find('.inner > ul'); var dropdownPadding = parseInt(dropdown.css('padding-left').slice(0, -2)) + parseInt(dropdown.css('padding-right').slice(0, -2)); if(!$j(this).hasClass('left_position') && !$j(this).hasClass('right_position')){ $j(this).find('.second').css('left',0); } var tallest = 0; $j(this).find('.second > .inner > ul > li').each(function() { var thisHeight = $j(this).height(); if(thisHeight > tallest) { tallest = thisHeight; } }); $j(this).find('.second > .inner > ul > li').height(tallest); var row_number; if($j(this).find('.second > .inner > ul > li').length > 4){ row_number = 4; }else{ row_number = $j(this).find('.second > .inner > ul > li').length; } var width = row_number*($j(this).find('.second > .inner > ul > li').outerWidth()); $j(this).find('.second > .inner > ul').width(width); if(!$j(this).hasClass('wide_background')){ if(!$j(this).hasClass('left_position') && !$j(this).hasClass('right_position')){ var left_position = ($j(window).width() - 2 * ($j(window).width()-$j(this).find('.second').offset().left))/2 + (width+dropdownPadding)/2; $j(this).find('.second').css('left',-left_position); } } else{ if(!$j(this).hasClass('left_position') && !$j(this).hasClass('right_position')){ var left_position = $j(this).find('.second').offset().left; $j(this).find('.second').css('left',-left_position); $j(this).find('.second').css('width',$j(window).width()); } } } if(!menu_dropdown_height_set){ $j(menu_items[i]).data('original_height', $j(menu_items[i]).find('.second').height() + 'px'); $j(menu_items[i]).find('.second').height(0); } if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) { $j(menu_items[i]).on("touchstart mouseenter",function(){ $j(menu_items[i]).find('.second').css({'height': $j(menu_items[i]).data('original_height'), 'overflow': 'visible', 'visibility': 'visible', 'opacity': '1'}); }).on("mouseleave", function(){ $j(menu_items[i]).find('.second').css({'height': '0px','overflow': 'hidden', 'visivility': 'hidden', 'opacity': '0'}); }); }else{ var config = { interval: 0, over: function(){ setTimeout(function() { $j(menu_items[i]).find('.second').addClass('drop_down_start'); $j(menu_items[i]).find('.second').stop().css({'height': $j(menu_items[i]).data('original_height')}); }, 150); }, timeout: 150, out: function(){ $j(menu_items[i]).find('.second').stop().css({'height': '0px'}); $j(menu_items[i]).find('.second').removeClass('drop_down_start'); } }; $j(menu_items[i]).hoverIntent(config); } } }); $j('.drop_down ul li.wide ul li a, .drop_down ul li.narrow ul li a').on('click',function(){ var $this = $j(this); if(!$this.next('ul').length && ($this.attr('href') !== "http://#") && ($this.attr('href') !== "#") && !$this.hasClass('no_link')) { setTimeout(function() { $this.mouseleave(); }, 500); } }); menu_dropdown_height_set = true; } /* ** Vertical menu toggle dropdown */ function initVerticalMenu(){ "use strict"; if ($j('.no-touch .vertical_menu_toggle').length) { var menu_items = $j('.no-touch .vertical_menu_toggle > ul > li'); var menu_items_2 = $j('.no-touch .vertical_menu_toggle ul li ul li'); menu_items.each( function(i) { if($j(menu_items[i]).hasClass('has_sub')){ var subitems_number = $j(menu_items[i]).find('.inner > ul > li').length; $j(menu_items[i]).hoverIntent({ over: function() { $j(menu_items[i]).addClass('open'); $j(menu_items[i]).find('.second').slideDown(subitems_number*40, 'easeInOutSine', function(){ $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); }); }, out: function() { //if(!$j(menu_items[i]).hasClass('active')){ $j(menu_items[i]).removeClass('open'); $j(menu_items[i]).find('.second').slideUp(subitems_number*40, 'easeInOutSine'); //} }, timeout: 1000 }); } }); menu_items_2.each( function(i) { if($j(menu_items_2[i]).hasClass('menu-item-has-children')){ var subitems_number = $j(menu_items_2[i]).find('ul > li').length; $j(menu_items_2[i]).hoverIntent({ over: function() { $j(menu_items_2[i]).addClass('open'); $j(menu_items_2[i]).find('ul').slideDown(subitems_number*40, 'easeInOutSine', function(){ $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); }); }, out: function() { $j(menu_items_2[i]).removeClass('open'); $j(menu_items_2[i]).find('ul').slideUp(subitems_number*40, 'easeInOutSine'); }, timeout: 1000 }); } }); } else if ($j('.vertical_menu_on_click').length) { var menu_items = $j('.vertical_menu_on_click > ul > li > a'); var menu_items_2 = $j('.vertical_menu_on_click ul li ul li a'); menu_items.each( function(i) { if($j(menu_items[i]).parent().hasClass('has_sub')){ $j(menu_items[i]).on('tap click',function(e) { e.preventDefault(); if(!$j(this).parent().hasClass('open')) { $j('.vertical_menu_on_click > ul > li').removeClass('open'); $j('.vertical_menu_on_click > ul > li').find('.second').slideUp('fast'); $j(this).parent().addClass('open'); $j(this).parent().find('.second').slideDown('slow', function () { $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); }); }else{ $j(this).parent().removeClass('open'); $j(this).parent().find('.second').slideUp('fast', function () { $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); }); } return false; }); } }); menu_items_2.each( function(i) { if($j(menu_items_2[i]).parent().hasClass('menu-item-has-children')){ $j(menu_items_2[i]).on('tap click',function(e) { e.preventDefault(); if(!$j(this).parent().hasClass('open')) { $j('.vertical_menu_on_click ul li ul li').removeClass('open'); $j('.vertical_menu_on_click ul li ul li').find('ul').slideUp('fast'); $j(this).parent().addClass('open'); $j(this).parent().find('ul').slideDown('slow', function () { $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); }); }else{ $j(this).parent().removeClass('open'); $j(this).parent().find('ul').slideUp('fast', function () { $j('.vertical_menu_area.with_scroll').getNiceScroll().resize(); }); } return false; }); } }); } else if ($j('.no-touch .vertical_menu_float').length){ //show dropdown to content on menu item hover, link is available on menu item click var menu_items = $j('.no-touch .vertical_menu_float > ul > li'); var menu_items_2 = $j('.no-touch .vertical_menu_float ul li ul li'); menu_items.each( function(i) { if($j(menu_items[i]).hasClass('has_sub')){ $j(menu_items[i]).hoverIntent({ over: function() { $j(menu_items[i]).addClass('open'); $j(menu_items[i]).find('.second').addClass('vertical_menu_start'); }, out: function() { //if(!$j(menu_items[i]).hasClass('active')){ $j(menu_items[i]).removeClass('open'); $j(menu_items[i]).find('.second').removeClass('vertical_menu_start'); }, timeout: 300 }); } }); menu_items_2.each( function(i) { if($j(menu_items_2[i]).hasClass('menu-item-has-children')){ var subitems_number = $j(menu_items_2[i]).find('ul > li').length; $j(menu_items_2[i]).hoverIntent({ over: function() { $j(menu_items_2[i]).addClass('open'); $j(menu_items_2[i]).find('ul').addClass('vertical_submenu_start'); }, out: function() { $j(menu_items_2[i]).removeClass('open'); $j(menu_items_2[i]).find('ul').removeClass('vertical_submenu_start'); }, timeout: 300 }); } }); } } /* ** Show/Hide Vertical menu for mobile */ function initVerticalMobileMenu(){ "use strict"; if ($j('.vertical_menu_toggle').length) { //register tap / click event for main menu item plus icon $j('.touch .vertical_menu_toggle > ul > li.has_sub > a .plus').on('tap click', function(e){ //first prevent event propagation and it's default behavior e.stopPropagation(); e.preventDefault(); //is dropdown for clicked item visible? if($j(this).parent().next('div.second').is(":visible")){ //if it is remove 'open' class and slide it up $j(this).parents('.touch .vertical_menu_toggle > ul > li.has_sub').removeClass('open'); $j(this).parent().next('div.second').slideUp(200); } else { //if it's not visible add 'open' class and slide it down $j(this).parents('.touch .vertical_menu_toggle > ul > li.has_sub').addClass('open'); $j(this).parent().next('div.second').slideDown(200); } }); //register tap / click event for second level main menu item plus icon $j('.touch .vertical_menu_toggle ul li ul li > a .plus').on('tap click', function(e){ //first prevent event propagation and it's default behavior e.stopPropagation(); e.preventDefault(); //is dropdown for clicked item visible? if($j(this).parent().next('ul').is(":visible")){ //if it is remove 'open' class and slide it up $j(this).parents('.touch .vertical_menu_toggle ul li ul li').removeClass('open'); $j(this).parent().next('ul').slideUp(200); } else { //if it's not visible add 'open' class and slide it down $j(this).parents('.touch .vertical_menu_toggle ul li ul li').addClass('open'); $j(this).parent().next('ul').slideDown(200); } }); } else if ($j('.vertical_menu_float').length){ $j('.touch .vertical_menu_float > ul > li.has_sub > a .plus').on('tap click', function(e){ //first prevent event propagation and it's default behavior e.stopPropagation(); e.preventDefault(); //is dropdown for clicked item visible? if($j(this).parent().next('div.second').hasClass('vertical_menu_start')){ //if it is remove 'open' class and 'vertical_menu_start' $j(this).parents('.touch .vertical_menu_float > ul > li.has_sub').removeClass('open'); $j(this).parents('.touch .vertical_menu_float > ul > li.has_sub').find('.second').removeClass('vertical_menu_start'); } else { //if it's not visible add 'open' class and 'vertical_menu_start' $j(this).parents('.touch .vertical_menu_float > ul > li.has_sub').addClass('open'); $j(this).parents('.touch .vertical_menu_float > ul > li.has_sub').find('.second').addClass('vertical_menu_start'); } }); //register tap / click event for second level main menu item plus icon $j('.touch .vertical_menu_float ul li ul li > a .plus').on('tap click', function(e){ //first prevent event propagation and it's default behavior e.stopPropagation(); e.preventDefault(); //is dropdown for clicked item visible? if($j(this).parent().next('ul').hasClass('vertical_submenu_start')){ //if it is remove 'open' class and slide it up $j(this).parents('.touch .vertical_menu_float ul li ul li').removeClass('open'); $j(this).parents('.touch .vertical_menu_float ul li ul li').find('ul').removeClass('vertical_submenu_start'); } else { //if it's not visible add 'open' class and slide it down $j(this).parents('.touch .vertical_menu_float ul li ul li').addClass('open'); $j(this).parents('.touch .vertical_menu_float ul li ul li').find('ul').addClass('vertical_submenu_start'); } }); } } /* ** Set transparency for left menu area */ function checkVerticalMenuTransparency(){ if($scroll !== 0){ $j('body.vertical_menu_transparency').removeClass('vertical_menu_transparency_on'); }else{ $j('body.vertical_menu_transparency').addClass('vertical_menu_transparency_on'); } } /* ** Show/Hide hidden Vertical menu */ function showHideVerticalMenu(){ if($j('.vertical_menu_hidden').length) { var vertical_menu = $j('aside.vertical_menu_area'); var vertical_menu_bottom_logo = $j('.vertical_menu_area_bottom_logo'); var hovered_flag = true; $j('.vertical_menu_hidden_button').on('click',function (e) { e.preventDefault(); if(hovered_flag) { hovered_flag = false; current_scroll = $j(window).scrollTop(); //current scroll is defined in front of "initSideMenu" function vertical_menu.addClass('active'); vertical_menu_bottom_logo.addClass('active'); }else{ hovered_flag = true; vertical_menu.removeClass('active'); vertical_menu_bottom_logo.removeClass('active'); } }); $j(window).scroll(function() { if(Math.abs($scroll - current_scroll) > 400){ hovered_flag = true; vertical_menu.removeClass('active'); vertical_menu_bottom_logo.removeClass('active'); } }); //take click outside vertical left/rifgt area and close it (function() { var Outclick, outclick, _this = this; Outclick = (function() { Outclick.name = 'Outclick'; function Outclick() { this.objects = []; } Outclick.prototype.check = function(element, event) { return !element.is(event.target) && element.has(event.target).length === 0; }; Outclick.prototype.trigger = function(e) { var execute, _this = this; execute = false; return $j.each(this.objects, function(index, el) { if (_this.check(el.container, e)) { if (el.related.length < 1) { execute = true; } else { $j.each(el.related, function(index, relation) { if (_this.check(relation, e)) { return execute = true; } else { execute = false; return false; } }); } if (execute) { return el.callback.call(el.container); } } }); }; return Outclick; })(); outclick = new Outclick; $j.fn.outclick = function(options) { var _this = this; if (options == null) { options = {}; } options.related || (options.related = []); options.callback || (options.callback = function() { return _this.hide(); }); return outclick.objects.push({ container: this, related: options.related, callback: options.callback }); }; $j(document).mouseup(function(e) { return outclick.trigger(e); }); }).call(this); $j(vertical_menu).outclick({ callback: function() { hovered_flag = true; vertical_menu.removeClass('active'); vertical_menu_bottom_logo.removeClass('active'); } }); } } /* ** Plugin for counter shortcode */ (function($) { "use strict"; $.fn.countTo = function(options) { // merge the default plugin settings with the custom options options = $.extend({}, $.fn.countTo.defaults, options || {}); // how many times to update the value, and how much to increment the value on each update var loops = Math.ceil(options.speed / options.refreshInterval), increment = (options.to - options.from) / loops; return $(this).each(function() { var _this = this, loopCount = 0, value = options.from, interval = setInterval(updateTimer, options.refreshInterval); function updateTimer() { value += increment; loopCount++; $(_this).html(value.toFixed(options.decimals)); if (typeof(options.onUpdate) === 'function') { options.onUpdate.call(_this, value); } if (loopCount >= loops) { clearInterval(interval); value = options.to; if (typeof(options.onComplete) === 'function') { options.onComplete.call(_this, value); } } } }); }; $.fn.countTo.defaults = { from: 0, // the number the element should start at to: 100, // the number the element should end at speed: 1000, // how long it should take to count between the target numbers refreshInterval: 100, // how often the element should be updated decimals: 0, // the number of decimal places to show onUpdate: null, // callback method for every time the element is updated, onComplete: null // callback method for when the element finishes updating }; })(jQuery); /* ** Counter from zero to defined number */ function initToCounter(){ "use strict"; if($j('.counter.zero').length){ $j('.counter.zero').each(function() { if(!$j(this).hasClass('executed')){ $j(this).addClass('executed'); if($j(this).parents('.vertical_split_slider').length){ $j(this).parent().css('opacity', '1'); var $max = parseFloat($j(this).text()); $j(this).countTo({ from: 0, to: $max, speed: 1500, refreshInterval: 100 }); } else{ $j(this).appear(function() { $j(this).parent().css('opacity', '1'); var $max = parseFloat($j(this).text()); $j(this).countTo({ from: 0, to: $max, speed: 1500, refreshInterval: 100 }); },{accX: 0, accY: -200}); } } }); } } /* ** Counter with random effect */ function initCounter(){ "use strict"; if($j('.counter.random').length){ $j('.counter.random').each(function() { if(!$j(this).hasClass('executed')){ $j(this).addClass('executed'); if($j(this).parents('.vertical_split_slider').length){ $j(this).parent().css('opacity', '1'); $j(this).absoluteCounter({ speed: 2000, fadeInDelay: 1000 }); } else{ $j(this).appear(function() { $j(this).parent().css('opacity', '1'); $j(this).absoluteCounter({ speed: 2000, fadeInDelay: 1000 }); },{accX: 0, accY: -200}); } } }); } } /* ** Countdown */ function initCountdown(){ "use strict"; if($j('.countdown').length){ $j('.countdown').each(function(){ var countdownId = $j(this).attr('id'); var $this = $j('#'+countdownId); var year = 0; var month = 0; var day = 0; var hour = 0; var minute = 0; var monthsLabel; var monthLabel; var daysLabel; var dayLabel; var hoursLabel; var hourLabel; var minutesLabel; var minuteLabel; var secondsLabel; var secondLabel; var tickf; var timezone; var digitfs; var labelfs; var color; if(typeof $this.data('year') !== 'undefined' && $this.data('year') !== false) { year = $this.data('year'); } if(typeof $this.data('month') !== 'undefined' && $this.data('month') !== false) { month = $this.data('month'); } if(typeof $this.data('day') !== 'undefined' && $this.data('day') !== false) { day = $this.data('day'); } if(typeof $this.data('hour') !== 'undefined' && $this.data('hour') !== false) { hour = $this.data('hour'); } if(typeof $this.data('minute') !== 'undefined' && $this.data('minute') !== false) { minute = $this.data('minute'); } if(typeof $this.data('monthslabel') !== 'undefined' && $this.data('monthslabel') !== false) { monthsLabel = $this.data('monthslabel'); } if(typeof $this.data('monthlabel') !== 'undefined' && $this.data('monthlabel') !== false) { monthLabel = $this.data('monthlabel'); } if(typeof $this.data('dayslabel') !== 'undefined' && $this.data('dayslabel') !== false) { daysLabel = $this.data('dayslabel'); } if(typeof $this.data('daylabel') !== 'undefined' && $this.data('daylabel') !== false) { dayLabel = $this.data('daylabel'); } if(typeof $this.data('hourslabel') !== 'undefined' && $this.data('hourslabel') !== false) { hoursLabel = $this.data('hourslabel'); } if(typeof $this.data('hourlabel') !== 'undefined' && $this.data('hourlabel') !== false) { hourLabel = $this.data('hourlabel'); } if(typeof $this.data('minuteslabel') !== 'undefined' && $this.data('minuteslabel') !== false) { minutesLabel = $this.data('minuteslabel'); } if(typeof $this.data('minutelabel') !== 'undefined' && $this.data('minutelabel') !== false) { minuteLabel = $this.data('minuteLabel'); } if(typeof $this.data('secondslabel') !== 'undefined' && $this.data('secondslabel') !== false) { secondsLabel = $this.data('secondslabel'); } if(typeof $this.data('secondlabel') !== 'undefined' && $this.data('secondlabel') !== false) { secondLabel = $this.data('secondlabel'); } if(typeof $this.data('tickf') !== 'undefined' && $this.data('tickf') !== false) { tickf = $this.data('tickf'); } if(typeof $this.data('timezone') !== 'undefined' && $this.data('timezone') !== false) { timezone = $this.data('timezone'); } if(typeof $this.data('digitfs') !== 'undefined' && $this.data('digitfs') !== false) { digitfs = $this.data('digitfs'); } if(typeof $this.data('labelfs') !== 'undefined' && $this.data('labelfs') !== false) { labelfs = $this.data('labelfs'); } if(typeof $this.data('color') !== 'undefined' && $this.data('color') !== false) { color = $this.data('color'); } $this.countdown({ until: new Date( year, month - 1, day, hour, minute, 44), labels: ['Years', monthsLabel, 'Weeks', daysLabel, hoursLabel, minutesLabel, secondsLabel], labels1: ['Year', monthLabel, 'Week', dayLabel, hourLabel, minuteLabel, secondLabel], format: 'ODHMS', timezone: timezone, padZeroes: true, significant: 0, onTick: function(){ if (digitfs !== 'undefined' && digitfs !== ''){ $this.find('.countdown-amount').css('font-size',digitfs + 'px').css('line-height',digitfs + 'px'); } if (labelfs !== 'undefined' && labelfs !== ''){ $this.find('.countdown-period').css('font-size',labelfs + 'px'); } if (color !== 'undefined' && color !== ''){ $this.find('.countdown_separator').css('background-color',color); } } }); }); } } /* ** Horizontal progress bars shortcode */ function initProgressBars(){ "use strict"; if($j('.q_progress_bar').length){ $j('.q_progress_bar').each(function() { if($j(this).parents('.vertical_split_slider').length){ initToCounterHorizontalProgressBar($j(this)); var percentage = $j(this).find('.progress_content').data('percentage'); $j(this).find('.progress_content').css('width', '0%'); $j(this).find('.progress_content').animate({'width': percentage+'%'}, 1500); $j(this).find('.progress_number_wrapper').css('width', '0%'); $j(this).find('.progress_number_wrapper').animate({'width': percentage+'%'}, 1500); } else { $j(this).appear(function() { initToCounterHorizontalProgressBar($j(this)); var percentage = $j(this).find('.progress_content').data('percentage'); $j(this).find('.progress_content').css('width', '0%'); $j(this).find('.progress_content').animate({'width': percentage+'%'}, 1500); $j(this).find('.progress_number_wrapper').css('width', '0%'); $j(this).find('.progress_number_wrapper').animate({'width': percentage+'%'}, 1500); },{accX: 0, accY: -200}); } }); } } /* ** Counter for horizontal progress bars percent from zero to defined percent */ function initToCounterHorizontalProgressBar($this){ "use strict"; var percentage = parseFloat($this.find('.progress_content').data('percentage')); if($this.find('.progress_number span').length) { $this.find('.progress_number span').each(function() { $j(this).parents('.progress_number_wrapper').css('opacity', '1'); $j(this).countTo({ from: 0, to: percentage, speed: 1500, refreshInterval: 50 }); }); } } /* ** Unordered list animation effect */ function initListAnimation(){ "use strict"; if($j('.animate_list').length > 0 && $j('.no_animation_on_touch').length === 0){ $j('.animate_list').each(function(){ $j(this).appear(function() { $j(this).find("li").each(function (l) { var k = $j(this); setTimeout(function () { k.animate({ opacity: 1, top: 0 }, 1500); }, 100*l); }); },{accX: 0, accY: -200}); }); } } /* ** Pie Chart shortcode */ function initPieChart(){ "use strict"; if($j('.q_percentage').length){ $j('.q_percentage').each(function() { var $barColor = piechartcolor; if($j(this).data('active') !== ""){ $barColor = $j(this).data('active'); } var $trackColor = '#eeeeee'; if($j(this).data('noactive') !== ""){ $trackColor = $j(this).data('noactive'); } var $line_width = 10; if($j(this).data('linewidth') !== ""){ $line_width = $j(this).data('linewidth'); } var $size = 174; $j(this).appear(function() { initToCounterPieChart($j(this)); $j(this).parent().css('opacity', '1'); $j(this).easyPieChart({ barColor: $barColor, trackColor: $trackColor, scaleColor: false, lineCap: 'butt', lineWidth: $line_width, animate: 1500, size: $size }); },{accX: 0, accY: -200}); }); } } /* ** Pie Chart shortcode */ function initPieChartWithIcon(){ "use strict"; if($j('.q_percentage_with_icon').length){ $j('.q_percentage_with_icon').each(function() { var $barColor = piechartcolor; if($j(this).data('active') !== ""){ $barColor = $j(this).data('active'); } var $trackColor = '#eeeeee'; if($j(this).data('noactive') !== ""){ $trackColor = $j(this).data('noactive'); } var $line_width = 10; if($j(this).data('linewidth') !== ""){ $line_width = $j(this).data('linewidth'); } var $size = 174; $j(this).appear(function() { $j(this).parent().css('opacity', '1'); $j(this).css('opacity', '1'); $j(this).easyPieChart({ barColor: $barColor, trackColor: $trackColor, scaleColor: false, lineCap: 'butt', lineWidth: $line_width, animate: 1500, size: $size }); },{accX: 0, accY: -200}); }); } } /* ** Counter for pie chart number from zero to defined number */ function initToCounterPieChart($this){ "use strict"; $j($this).css('opacity', '1'); var $max = parseFloat($j($this).find('.tocounter').text()); $j($this).find('.tocounter').countTo({ from: 0, to: $max, speed: 1500, refreshInterval: 50 }); } /* ** Init Portfolio list and Portfolio Filter */ function initPortfolio(){ "use strict"; if($j('.projects_holder_outer:not(.masonry_with_space)').length){ $j('.projects_holder_outer').each(function(){ $j('.filter_holder').each(function(){ var filter_height = 0; $j(this).find('li.filter').each(function(){ filter_height += $j(this).height(); }); $j(this).on('click',function(data){ var $drop = $j(this), $bro = $drop.siblings('.hidden'); if(!$drop.hasClass('expanded')){ $drop.find('ul').css('z-index','1000'); $drop.find('ul').height(filter_height+39); //36 is height of first default item + 1 border * 2 + 1 border on li $drop.addClass('expanded'); var label = $drop.find('.label span'); label.text(label.attr('data-label')); } else { $drop.find('ul').height(36); $drop.removeClass('expanded'); var $selected = $j(data.target), ndx = $selected.index(); if($bro.length){ $bro.find('option').removeAttr('selected').eq(ndx).attr('selected','selected').change(); } } }); }); $j('.filter_holder .filter').on('click',function(){ var $this = $j(this).text(); var dropLabels = $j('.filter_holder').find('.label span'); dropLabels.each(function(){ $j(this).text($this); }); }); var currentPortfolio = $j(this).find('.projects_holder'); if(currentPortfolio.hasClass('v1')){ var timeArray= new Array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25); }else if(currentPortfolio.hasClass('v2')){ var timeArray= new Array(1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20); }else if(currentPortfolio.hasClass('v3')){ var timeArray= new Array(1,2,3,2,3,4,3,4,5,4,5,6,5,6,7,6,7,8,7,8,9,8,9,10,9,10,11,10,11,12,11,12,13,12,13,14,13,14,15,14,15,16,15,16,17,16,17,18,17,18,19,18,19,20,19,20,21,20,21,22); }else if(currentPortfolio.hasClass('v4')){ var timeArray= new Array(1,2,3,4,2,3,4,5,3,4,5,6,4,5,6,7,5,6,7,8,6,7,8,9,7,8,9,10,8,9,10,11,9,10,11,12,10,11,12,13,11,12,13,14,12,13,14,15,13,14,15,16,14,15,16,17,15,16,17,18,16,17,18,19,17,18,19,20,18,19,20,21); }else if(currentPortfolio.hasClass('v5')){ var timeArray= new Array(1,2,3,4,5,2,3,4,5,6,3,4,5,6,7,4,5,6,7,8,5,6,7,8,9,6,7,8,9,10,7,8,9,10,11,8,9,10,11,12,9,10,11,12,13,10,11,12,13,14,11,12,13,14,15,12,13,14,15,16,13,14,15,16,17,14,15,16,17,18,15,16,17,18,19,20,16,17,18,19,20,17,18,19,20,21,18,19,20,21,22,19,20,21,22,23); }else if(currentPortfolio.hasClass('v6')){ var timeArray= new Array(1,2,3,4,5,6,2,3,4,5,6,7,3,4,5,6,7,8,4,5,6,7,8,9,5,6,7,8,9,10,6,7,8,9,10,11,7,8,9,10,11,12,8,9,10,11,12,13,9,10,11,12,13,14,10,11,12,13,14,15,11,12,13,14,15,16,12,13,14,15,16,17,13,14,15,16,17,18,14,15,16,17,18,19,15,16,17,18,19,20,16,17,18,19,20,21,17,18,19,20,21,22); } currentPortfolio.mixitup({ showOnLoad: 'all', transitionSpeed: 600, minHeight: 150, onMixLoad: function(){ $j('.projects_holder').addClass('hideItems'); $j('.projects_holder article').css('visibility','visible'); if(currentPortfolio.hasClass('portfolio_one_by_one')) { currentPortfolio.find('article').each(function(l) { var currentPortfolioItem = $j(this); if($j('.vertical_split_slider').length){ var acc = 0; }else{ var acc = -150; } setTimeout(function() { currentPortfolioItem.addClass('show'); }, 100*l); }); } if(currentPortfolio.hasClass('slide_from_left')) { currentPortfolio.find('article').each(function(i) { var currentPortfolioItem = $j(this); setTimeout(function() { currentPortfolioItem.addClass('show'); }, (Math.random() * 200)); }); } if(currentPortfolio.hasClass('slide_from_top')) { currentPortfolio.find('article').each(function(i) { var currentPortfolioItem = $j(this); setTimeout(function() { currentPortfolioItem.addClass('show'); }, timeArray[i]*50); }); } if(currentPortfolio.hasClass('diagonal_fade')) { currentPortfolio.find('article').each(function(i) { var currentPortfolioItem = $j(this); setTimeout(function() { currentPortfolioItem.addClass('show'); }, timeArray[i]*50); }); } initParallax(); }, onMixEnd: function(){ initParallax(); } }); }); } } /* ** Init z-index for portfolio items */ function initPortfolioZIndex(){ "use strict"; if($j('.projects_holder_outer.portfolio_no_space').length){ $j('.no_space.hover_text article').each(function(i){ $j(this).css('z-index', i +10); }); } } function initPortfolioMasonry(){ "use strict"; if($j('.projects_masonry_holder, .masonry_with_space').length){ $j('.projects_masonry_holder, .masonry_with_space .projects_holder').each(function(){ var $window = jQuery(window); var $this = $j(this); $this.waitForImages(function(){ $this.animate({opacity:1}); if($j('.projects_masonry_holder').length){ resizeMasonry($this); } $this.isotope({ resizable: false, itemSelector: '.portfolio_masonry_item, .mix', layoutMode: 'masonry' }).isotope( 'layout' ); if($j('.projects_masonry_holder').length){ setPortfolioMasZIndex(); $window.resize(function() {resizeMasonry($this); setPortfolioMasZIndex();}); } if($this.hasClass('portfolio_one_by_one')) { $this.find('article').each(function(l) { var $this = $j(this); setTimeout(function() { $this.addClass('show'); }, 100*l); }); } if($this.hasClass('portfolio_fade_from_bottom')) { $this.find('article').each(function(l) { $j(this).appear(function() { $j(this).addClass('show'); },{accX: 0, accY: -150}); }); } }); }); } } var portfolio_width; function resizeMasonry(container){ var $window = jQuery(window); if($j('.full_width').length){ if($j('body').hasClass('vertical_menu_enabled') && $window_width > 1000){ portfolio_width = $window.innerWidth() - $j('.vertical_menu_area').innerWidth(); }else { portfolio_width = $window.innerWidth(); } }else{ var closest_container = container.closest('.container_inner'); if(closest_container.has('.column_inner').length) { portfolio_width = container.closest('.column_inner').innerWidth(); } else { portfolio_width = closest_container.innerWidth(); } } container.width(portfolio_width); if(container.hasClass('gs4')){ var $cols = 4; if(portfolio_width <= 1000 && portfolio_width > 480){ $cols = 2; }else if(portfolio_width <= 480){ $cols = 1; } } else{ var $cols = 5; if(portfolio_width > 1600){ $cols = 5; }else if(portfolio_width <= 1600 && portfolio_width > 1200){ $cols = 4; }else if(portfolio_width <= 1200 && portfolio_width > 1000){ $cols = 3; }else if(portfolio_width <= 1000 && portfolio_width > 480){ $cols = 2; }else if(portfolio_width <= 480){ $cols = 1; } } var largeItemHeight; if(container.find('article[class*="default"]:first img').height()){ largeItemHeight = container.find('article[class*="default"]:first img').height(); }else if(container.find('article[class*="large_width"]:not(.large_width_height):first img').height()){ largeItemHeight = container.find('article[class*="large_width"]:not(.large_width_height):first img').height(); }else{ largeItemHeight = (container.find('article[class*="large_width_height"]:first img').height()) ? (container.find('article[class*="large_width_height"]:first img').height())/2 : (container.find('article[class*="large_height"]:first img').height())/2; } var double = ($window.innerWidth() > 480) ? 2 : 1 ; container.find('article[class*="large_width_height"] img, article[class*="large_height"] img').css('height',(largeItemHeight*double)); container.isotope({ masonry: { columnWidth: portfolio_width / parseInt($cols)} }); } function setPortfolioMasZIndex(){ var $elemXPos = {}; var $elemZIndex = {}; $j('.projects_masonry_holder article').each(function(){ $elemXPos[$j(this).index()] = getPortfolioXPos($j(this).css('left')); }); var $elemXPosArray = $j.map($elemXPos, function (value) { return value; }); $elemXPosArray = cleanPortfolioMasXArray($elemXPosArray); $elemXPosArray.sort(function(x,y){return x-y}); for(var i = 0; i < $elemXPosArray.length; i++){ $elemZIndex[$elemXPosArray[i]] = i*10; } $j.each($elemXPos,function(key,val){ var $zi; var $bgd = val; $j.each($elemZIndex,function(key,val){ if($bgd == key) { $zi = val; } }); $j('.projects_masonry_holder article:eq('+key+')').css('z-index',$zi); }); } function cleanPortfolioMasXArray($elemXPosArray) { var i; var length = $elemXPosArray.length; var $elemXPosOutArray = []; var tmp = {}; for (i = 0; i < length; i++) { tmp[$elemXPosArray[i]] = 0; } for (i in tmp) { $elemXPosOutArray.push(i); } return $elemXPosOutArray; } function getPortfolioXPos(css) { //return css.substr(7, css.length - 8).split(', ')[4]; return css.substr(0, css.length - 2); } function initPortfolioMasonryFilter(){ "use strict"; var portfolioIsotopeAnimation = null; $j('.filter:first').addClass('current'); $j('.filter').click(function(){ clearTimeout(portfolioIsotopeAnimation); $j('.isotope, .isotope .isotope-item').css('transition-duration','0.8s'); portfolioIsotopeAnimation = setTimeout(function(){ $j('.isotope, .isotope .isotope-item').css('transition-duration','0s'); },700); var selector = $j(this).attr('data-filter'); $j('.projects_masonry_holder, .masonry_with_space .projects_holder').isotope({ filter: selector }); $j(".filter").removeClass("current"); $j(this).addClass("current"); setTimeout(setPortfolioMasZIndex(),700); return false; }); } function initServiceAnimation(){ "use strict"; if($j(".fade_in_circle_holder").length > 0 && $j('.no_animation_on_touch').length === 0){ $j('.fade_in_circle_holder').each(function(){ $j(this).appear(function(){ $j(this).addClass('animate_circle'); },{accX: 0, accY: -200}); }); } } function checkTitleToShowOrHide(){ if($j('.title_outer.animate_title_area').length){ var title_area_height = $j('.title_outer').data('height'); if($scroll > $j('.title').height()){ $j('.title_outer').css({'height':title_area_height, 'opacity':'1', 'overflow':'visible'}); } } } /* ** Title area animation */ function initTitleAreaAnimation(){ if($j('.title_outer.animate_title_area').length){ var title_area_height = $j('.title_outer').data('height'); if($j('.title_outer').hasClass('with_image')){ title_area_height = $j('.image.responsive').height(); } if($scroll < $j('.title').height()){ $j('.title_outer').animate({ height: title_area_height, opacity: 1}, 500, function(){ $j(this).css({'overflow':'visible'}); initPortfolioSingleInfo(); if($j('nav.content_menu').length > 0){ content_menu_position = $j('nav.content_menu').offset().top; contentMenuPosition(); } }); } } } /* ** Title image with parallax effect */ function initParallaxTitle(){ "use strict"; if(($j('.title').length > 0) && ($j('.touch').length === 0)){ if($j('.title.has_fixed_background').length){ var $background_size_width = parseInt($j('.title.has_fixed_background').css('background-size').match(/\d+/)); var title_holder_height = $j('.title.has_fixed_background').height(); var title_rate = (title_holder_height / 10000) * 7; var title_distance = $scroll - $j('.title.has_fixed_background').offset().top; var title_bpos = -(title_distance * title_rate); $j('.title.has_fixed_background').css({'background-position': 'center '+ (0+add_for_admin_bar) +'px' }); if($j('.title.has_fixed_background').hasClass('zoom_out')){ $j('.title.has_fixed_background').css({'background-size': $background_size_width-$scroll + 'px auto'}); } } $j(window).on('scroll', function() { if($j('.title.has_fixed_background').length){ var title_distance = $scroll - $j('.title.has_fixed_background').offset().top; var title_bpos = -(title_distance * title_rate); $j('.title.has_fixed_background').css({'background-position': 'center ' + (title_bpos+add_for_admin_bar) + 'px' }); if($j('.title.has_fixed_background').hasClass('zoom_out')){ $j('.title.has_fixed_background').css({'background-size': $background_size_width-$scroll + 'px auto'}); } } }); } } /* Plugin: jQuery Parallax Version 1.1.3 Author: Ian Lunn Twitter: @IanLunn Author URL: http://www.ianlunn.co.uk/ Plugin URL: http://www.ianlunn.co.uk/plugins/jquery-parallax/ Dual licensed under the MIT and GPL licenses: http://www.opensource.org/licenses/mit-license.php http://www.gnu.org/licenses/gpl.html */ (function( $ ){ var $window = $(window); var windowHeight = $window.height(); $window.resize(function () { windowHeight = $window.height(); }); $.fn.parallax = function(xpos, speedFactor, outerHeight) { var $this = $(this); var getHeight; var firstTop; var paddingTop = 0; //get the starting position of each element to have parallax applied to it $this.each(function(){ firstTop = $this.offset().top; }); if (outerHeight) { getHeight = function(jqo) { return jqo.outerHeight(true); }; } else { getHeight = function(jqo) { return jqo.height(); }; } // setup defaults if arguments aren't specified if (arguments.length < 1 || xpos === null) xpos = "50%"; if (arguments.length < 2 || speedFactor === null) speedFactor = 0.1; if (arguments.length < 3 || outerHeight === null) outerHeight = true; // function to be called whenever the window is scrolled or resized function update(){ var pos = $window.scrollTop(); $this.each(function(){ var $element = $(this); var top = $element.offset().top; var height = getHeight($element); // Check if totally above or totally below viewport if (top + height < pos || top > pos + windowHeight) { return; } $this.css('backgroundPosition', xpos + " " + Math.round((firstTop - pos) * speedFactor) + "px"); }); } $window.bind('scroll', update).resize(update); update(); }; })(jQuery); /* ** Sections with parallax background image */ function initParallax(){ "use strict"; if($j('.parallax_section_holder').length){ $j('.parallax_section_holder').each(function() { var speed = $j(this).data('speed')*0.4; $j(this).parallax("50%", speed); }); } } /* ** Smooth scroll functionality for Side Area */ function initSideAreaScroll(){ "use strict"; if($j('.side_menu').length){ $j(".side_menu").niceScroll({ scrollspeed: 60, mousescrollstep: 40, cursorwidth: 0, cursorborder: 0, cursorborderradius: 0, cursorcolor: "transparent", autohidemode: false, horizrailenabled: false }); } } /* ** Smooth scroll functionality for Vertical Menu Area Toogle style */ function initVerticalAreaMenuScroll(){ "use strict"; if($j('.vertical_menu_area.with_scroll').length){ $j(".vertical_menu_area.with_scroll").niceScroll({ scrollspeed: 60, mousescrollstep: 40, cursorwidth: 0, cursorborder: 0, cursorborderradius: 0, cursorcolor: "transparent", autohidemode: false, horizrailenabled: false }); } } /* ** Load more portfolios */ function loadMore(){ "use strict"; var i = 1; $j('.load_more a').on('click', function(e) { e.preventDefault(); var link = $j(this).attr('href'); var $content = '.projects_holder'; var $anchor = '.portfolio_paging .load_more a'; var $next_href = $j($anchor).attr('href'); // Get URL for the next set of posts var filler_num = $j('.projects_holder .filler').length; var load_more_holder = $j('.portfolio_paging'); var loading_holder = $j('.portfolio_paging_loading'); load_more_holder.hide(); loading_holder.show(); $j.get(link+'', function(data){ $j('.projects_holder .filler').slice(-filler_num).remove(); var $new_content = $j($content, data).wrapInner('').html(); // Grab just the content $next_href = $j($anchor, data).attr('href'); // Get the new href $j($content, data).waitForImages(function() { $j('article.mix:last').after($new_content); // Append the new content $j('.projects_holder article').css('visibility','visible'); $j('article:not(.show)').each(function(l){ $j(this).addClass('show'); }); if($j('.masonry_with_space').length){ $j('.masonry_with_space .projects_holder').isotope('reloadItems').isotope(); }else{ var min_height = $j('article.mix:first').height(); $j('article.mix').css('min-height',min_height); $j('.projects_holder').mixitup('remix','all'); } prettyPhoto(); if($j('.load_more').attr('rel') > i) { $j('.load_more a').attr('href', $next_href); // Change the next URL } else { $j('.load_more').remove(); } $j('.projects_holder .portfolio_paging:last').remove(); // Remove the original navigation $j('article.mix').css('min-height',0); load_more_holder.show(); loading_holder.hide(); }); }); i++; }); } /* ** Picture popup for portfolio lists and portfolio single */ function prettyPhoto(){ "use strict"; $j('a[data-rel]').each(function() { $j(this).attr('rel', $j(this).data('rel')); }); $j("a[rel^='prettyPhoto']").prettyPhoto({ animation_speed: 'normal', /* fast/slow/normal */ slideshow: false, /* false OR interval time in ms */ autoplay_slideshow: false, /* true/false */ opacity: 0.80, /* Value between 0 and 1 */ show_title: true, /* true/false */ allow_resize: true, /* Resize the photos bigger than viewport. true/false */ horizontal_padding: 0, default_width: 650, default_height: 400, counter_separator_label: '/', /* The separator for the gallery counter 1 "of" 2 */ theme: 'pp_default', /* light_rounded / dark_rounded / light_square / dark_square / facebook */ hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */ wmode: 'opaque', /* Set the flash wmode attribute */ autoplay: true, /* Automatically start videos: True/False */ modal: false, /* If set to true, only the close button will close the window */ overlay_gallery: false, /* If set to true, a gallery will overlay the fullscreen image on mouse over */ keyboard_shortcuts: true, /* Set to false if you open forms inside prettyPhoto */ deeplinking: false, social_tools: false }); } /* ** Show/Hide Mobile menu */ function initMobileMenu(){ "use strict"; $j(".mobile_menu_button > span").on('tap click', function(e){ e.preventDefault(); if ($j(".mobile_menu > ul").is(":visible")){ $j(".mobile_menu > ul").slideUp(200); } else { $j(".mobile_menu > ul").slideDown(200); } }); $j(".mobile_menu > ul > li.has_sub > span.mobile_arrow, .mobile_menu > ul > li.has_sub > h3, .mobile_menu > ul > li.has_sub > a[href*=#]").on('tap click', function(e){ e.preventDefault(); if ($j(this).closest('li.has_sub').find("> ul.sub_menu").is(":visible")){ $j(this).closest('li.has_sub').find("> ul.sub_menu").slideUp(200); $j(this).closest('li.has_sub').removeClass('open_sub'); } else { $j(this).closest('li.has_sub').addClass('open_sub'); $j(this).closest('li.has_sub').find("> ul.sub_menu").slideDown(200); } }); $j(".mobile_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > span.mobile_arrow, .mobile_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > h3, .mobile_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > a[href*=#]").on('tap click', function(e){ e.preventDefault(); if ($j(this).parent().find("ul.sub_menu").is(":visible")){ $j(this).parent().find("ul.sub_menu").slideUp(200); $j(this).parent().removeClass('open_sub'); } else { $j(this).parent().addClass('open_sub'); $j(this).parent().find("ul.sub_menu").slideDown(200); } }); $j(".mobile_menu ul li > a, .q_logo a").on('click', function(){ if(($j(this).attr('href') !== "http://#") && ($j(this).attr('href') !== "#")){ $j(".mobile_menu > ul").slideUp(); } }); } /* ** Init flexslider for portfolio single */ function initFlexSlider(){ "use strict"; $j('.flexslider').each(function(){ var interval = 8000; if(typeof $j(this).data('interval') !== 'undefined' && $j(this).data('interval') !== false) { interval = parseFloat($j(this).data('interval')) * 1000; } var slideshow = true; if(interval === 0) { slideshow = false; } var animation = 'slide'; if(typeof $j(this).data('flex_fx') !== 'undefined' && $j(this).data('flex_fx') !== false) { animation = $j(this).data('flex_fx'); } $j(this).flexslider({ animationLoop: true, controlNav: false, useCSS: false, pauseOnAction: true, pauseOnHover: true, slideshow: slideshow, animation: animation, prevText: "
", nextText: "
", animationSpeed: 600, slideshowSpeed: interval, start: function(){ setTimeout(function(){$j(".flexslider").fitVids();},100); } }); $j('.flex-direction-nav a').click(function(e){ e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); }); }); } /* ** Init fitVideo function for responsive video files */ function fitVideo(){ "use strict"; $j(".portfolio_images").fitVids(); $j(".video_holder").fitVids(); $j(".format-video .post_image").fitVids(); $j(".format-video .q_masonry_blog_post_image").fitVids(); } /* ** Function for follow portfolio single descripton */ var $scrollHeight; function initPortfolioSingleInfo(){ "use strict"; var $sidebar = $j(".portfolio_single_follow"); if($j(".portfolio_single_follow").length > 0){ var offset = $sidebar.offset(); $scrollHeight = $j(".portfolio_container").height(); var $scrollOffset = $j(".portfolio_container").offset(); var $window = $j(window); var $headerHeight = parseInt($j('header.page_header').css('height'), 10); $window.scroll(function() { if($window.width() > 960){ if ($window.scrollTop() + $headerHeight + 3 > offset.top) { if ($window.scrollTop() + $headerHeight + $sidebar.height() + 24 < $scrollOffset.top + $scrollHeight) { $sidebar.stop().animate({ marginTop: $window.scrollTop() - offset.top + $headerHeight }); } else { $sidebar.stop().animate({ marginTop: $scrollHeight - $sidebar.height() - 24 }); } } else { $sidebar.stop().animate({ marginTop: 0 }); } }else{ $sidebar.css('margin-top',0); } }); } } /* ** Init tabs shortcodes */ function initTabs(){ "use strict"; if($j('.q_tabs').length){ $j('.q_tabs').appear(function() { $j('.q_tabs').css('visibility', 'visible'); },{accX: 0, accY: -100}); var $tabsNav = $j('.tabs-nav'); var $tabsNavLis = $tabsNav.children('li'); $tabsNav.each(function() { var $this = $j(this); $this.next().children('.tab-content').stop(true,true).hide().first().show(); $this.children('li').first().addClass('active').stop(true,true).show(); }); $tabsNavLis.on('click', function(e) { var $this = $j(this); $this.siblings().removeClass('active').end().addClass('active'); $this.parent().next().children('.tab-content').stop(true,true).hide().siblings( $this.find('a').attr('href') ).fadeIn(); e.preventDefault(); }); } } /* ** Init accordion and toogle shortcodes */ function initAccordion() { "use strict"; if($j(".q_accordion_holder").length){ $j(".q_accordion_holder").appear(function() { $j(".q_accordion_holder").css('visibility', 'visible'); },{accX: 0, accY: -100}); if ($j(".accordion").length) { $j(".accordion").accordion({ animate: "swing", collapsible: true, active: false, icons: "", heightStyle: "content", activate: function(event, ui) { initParallax(); } }); //define custom options for each accordion $j(".accordion").each(function() { var activeTab = parseInt($j(this).data('active-tab')); if(activeTab !== "") { activeTab = activeTab - 1; // - 1 because active tab is set in 0 index base $j(this).accordion('option', 'active', activeTab); } var borderRadius = parseInt($j(this).data('border-radius')); if(borderRadius !== "") { $j(this).find('.accordion_mark').css('border-radius', borderRadius+"px"); } var collapsible = ($j(this).data('collapsible') == 'yes') ? true : false; $j(this).accordion('option', 'collapsible', collapsible); $j(this).accordion('option', 'collapsible', collapsible); }); } $j(".toggle").addClass("accordion ui-accordion ui-accordion-icons ui-widget ui-helper-reset") .find(".title-holder") .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom") .hover(function() { $j(this).toggleClass("ui-state-hover"); }) .click(function() { $j(this) .toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom") .next().toggleClass("ui-accordion-content-active").slideToggle(400); return false; }) .next() .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom") .hide(); $j(".toggle").each(function() { var activeTab = parseInt($j(this).data('active-tab')); if(activeTab !== "" && activeTab >= 1) { activeTab = activeTab - 1; // - 1 because active tab is set in 0 index base $j(this).find('.ui-accordion-content').eq(activeTab).show(); $j(this).find('.ui-accordion-header').eq(activeTab).addClass('ui-state-active'); //set active accordion header } }); } } /* ** Function to enable link in accordion */ function initAccordionContentLink(){ "use strict"; if($j(".accordion").length){ $j('.accordion_holder .accordion_inner .accordion_content a').click(function(){ if($j(this).attr('target') === '_blank'){ window.open($j(this).attr('href'),'_blank'); }else{ window.open($j(this).attr('href'),'_self'); } return false; }); } } /* ** Init testimonials shortcode */ function initTestimonials(){ "use strict"; if($j('.testimonials_carousel').length){ $j('.testimonials_carousel').each(function(){ var interval = 5000; if(typeof $j(this).data('auto-rotate-slides') !== 'undefined' && $j(this).data('auto-rotate-slides') !== false) { interval = parseFloat($j(this).data('auto-rotate-slides')) * 1000; } var slideshow = true; if(interval === 0) { slideshow = false; } var animation = 'fade'; if(typeof $j(this).data('animation-type') !== 'undefined' && $j(this).data('animation-type') !== false) { animation = $j(this).data('animation-type'); } var directionNav = true; if(typeof $j(this).data('show-navigation') !== 'undefined') { directionNav = $j(this).data('show-navigation') == 'no' ? false : true; } var animationSpeed = 600; if(typeof $j(this).data('animation-speed') !== 'undefined' && $j(this).data('animation-speed') !== false) { animationSpeed = $j(this).data('animation-speed'); } $j(this).flexslider({ animationLoop: true, controlNav: false, directionNav: directionNav, useCSS: false, pauseOnAction: true, pauseOnHover: false, slideshow: slideshow, animation: animation, itemMargin: 25, minItems: 1, maxItems: 1, animationSpeed: animationSpeed, slideshowSpeed: interval, start: function(slider){ initParallax(); } }); }); } } /* ** Function to close message shortcode */ function initMessages(){ "use strict"; if($j('.q_message').length){ $j('.q_message').each(function(){ $j(this).find('.close').click(function(e){ e.preventDefault(); $j(this).parent().parent().fadeOut(500); }); }); } } /* ** Init Element Animations */ function initElementsAnimation(){ "use strict"; if($j(".element_from_fade").length > 0 && $j('.no_animation_on_touch').length === 0){ $j('.element_from_fade').each(function(){ var $this = $j(this); $this.appear(function() { $this.addClass('element_from_fade_on'); },{accX: 0, accY: -100}); }); } if($j(".element_from_left").length > 0 && $j('.no_animation_on_touch').length === 0){ $j('.element_from_left').each(function(){ var $this = $j(this); $this.appear(function() { $this.addClass('element_from_left_on'); },{accX: 0, accY: -100}); }); } if($j(".element_from_right").length > 0 && $j('.no_animation_on_touch').length === 0){ $j('.element_from_right').each(function(){ var $this = $j(this); $this.appear(function() { $this.addClass('element_from_right_on'); },{accX: 0, accY: -100}); }); } if($j(".element_from_top").length > 0 && $j('.no_animation_on_touch').length === 0){ $j('.element_from_top').each(function(){ var $this = $j(this); $this.appear(function() { $this.addClass('element_from_top_on'); },{accX: 0, accY: -100}); }); } if($j(".element_from_bottom").length > 0 && $j('.no_animation_on_touch').length === 0){ $j('.element_from_bottom').each(function(){ var $this = $j(this); $this.appear(function() { $this.addClass('element_from_bottom_on'); },{accX: 0, accY: -100}); }); } if($j(".element_transform").length > 0 && $j('.no_animation_on_touch').length === 0){ $j('.element_transform').each(function(){ var $this = $j(this); $this.appear(function() { $this.addClass('element_transform_on'); },{accX: 0, accY: -100}); }); } } /* ** Init audio player for blog layout */ function fitAudio(){ "use strict"; $j('audio.blog_audio').mediaelementplayer({ audioWidth: '100%' }); } /* ** Init masonry layout for blog template */ function initBlog() { "use strict"; if($j('.blog_holder.masonry').length) { var width_blog = $j(this).closest('.container_inner').width(); if($j('.blog_holder.masonry').closest(".column_inner").length) { width_blog = $j('.blog_holder.masonry').closest(".column_inner").width(); } $j('.blog_holder.masonry').width(width_blog); var $container = $j('.blog_holder.masonry'); $container.waitForImages(function() { setTimeout(function() { $container.isotope({ itemSelector: 'article', resizable: false, masonry: {columnWidth: '.blog_holder_grid_sizer', gutter: '.blog_holder_grid_gutter'} }); $j('.blog_holder.masonry').animate({opacity: "1"}, 500); }, 400); }); $j('.filter').click(function() { var selector = $j(this).attr('data-filter'); $container.isotope({filter: selector}); return false; }); if($container.hasClass('masonry_infinite_scroll')) { $container.infinitescroll({ navSelector: '.blog_infinite_scroll_button span', nextSelector: '.blog_infinite_scroll_button span a', itemSelector: 'article', loading: { finishedMsg: finished_text, msgText: loading_text } }, // call Isotope as a callback function(newElements) { $container.isotope('appended', $j(newElements)); fitVideo(); fitAudio(); initFlexSlider(); setTimeout(function() { $j('.blog_holder.masonry').isotope('layout'); }, 400); } ); } else if($container.hasClass('masonry_load_more')) { var i = 1; $j('.blog_load_more_button a').off('click tap').on('click tap', function(e) { e.preventDefault(); var load_more_holder = $j('.blog_load_more_button'); var load_more_loading = $j('.blog_load_more_button_loading'); load_more_holder.hide(); load_more_loading.show(); var link = $j(this).attr('href'); var $content = '.masonry_load_more'; var $anchor = '.blog_load_more_button a'; var $next_href = $j($anchor).attr('href'); $j.get(link + '', function(data) { var $new_content = $j($content, data).wrapInner('').html(); $next_href = $j($anchor, data).attr('href'); $container.append($j($new_content)).isotope('reloadItems').isotope({sortBy: 'original-order'}); fitVideo(); fitAudio(); initFlexSlider(); setTimeout(function() { $j('.blog_holder.masonry').isotope('layout'); }, 400); load_more_holder.show(); load_more_loading.hide(); if($j('.blog_load_more_button span').attr('rel') > i) { $j('.blog_load_more_button a').attr('href', $next_href); // Change the next URL } else { $j('.blog_load_more_button').remove(); } }); i++; }); } } } /* ** Init full width masonry layout for blog template */ function initBlogMasonryFullWidth(){ "use strict"; if($j('.masonry_full_width').length){ var width_blog = $j('.full_width_inner').width(); $j('.masonry_full_width').width(width_blog); var $container = $j('.masonry_full_width'); $j('.filter').click(function(){ var selector = $j(this).attr('data-filter'); $container.isotope({ filter: selector }); return false; }); if( $container.hasClass('masonry_infinite_scroll')){ $container.infinitescroll({ navSelector : '.blog_infinite_scroll_button span', nextSelector : '.blog_infinite_scroll_button span a', itemSelector : 'article', loading: { finishedMsg: finished_text, msgText : loading_text } }, // call Isotope as a callback function( newElements ) { $container.isotope( 'appended', $j( newElements ) ); fitVideo(); fitAudio(); initFlexSlider(); setTimeout(function() { $j('.blog_holder.masonry_full_width').isotope( 'layout'); }, 400); } ); }else if($container.hasClass('masonry_load_more')){ var i = 1; $j('.blog_load_more_button a').off('click tap').on('click tap', function(e) { e.preventDefault(); var link = $j(this).attr('href'); var $content = '.masonry_load_more'; var $anchor = '.blog_load_more_button a'; var $next_href = $j($anchor).attr('href'); $j.get(link+'', function(data){ var $new_content = $j($content, data).wrapInner('').html(); $next_href = $j($anchor, data).attr('href'); $container.append( $j( $new_content) ).isotope( 'reloadItems' ).isotope({ sortBy: 'original-order' }); fitVideo(); fitAudio(); initFlexSlider(); setTimeout(function() { $j('.blog_holder.masonry_full_width').isotope( 'layout'); }, 400); if($j('.blog_load_more_button span').attr('rel') > i) { $j('.blog_load_more_button a').attr('href', $next_href); // Change the next URL } else { $j('.blog_load_more_button').remove(); } }); i++; }); } $container.waitForImages(function() { setTimeout(function() { $container.isotope({ itemSelector: 'article', resizable: false, masonry: { columnWidth: '.blog_holder_grid_sizer',gutter: '.blog_holder_grid_gutter'} }); $j('.masonry_full_width').animate({opacity: "1"}, 500); }, 400); }); } } /* ** Min height for smaall image blog */ function initSmallImageBlogHeight(){ "use strict"; if($j('.blog_small_image').length){ $j('article').each(function() { $j(this).find('.post_text_inner').css('min-height', $j(this).find('.post_image').height() - 46); //46 is top and bottom padding }); } } /* ** Init masonry layout for blog masonry shortcode */ function initQBlog(){ "use strict"; if($j('.q_masonry_blog').length){ $j('.q_masonry_blog').each(function() { var width_blog; width_blog = $j(this).parents('.container_inner').width(); if($j('.full_width').length && $j(this).parents('.grid_section').length == 0){ width_blog = $j('.full_width').width(); }else{ if($j(this).parents(".column_inner").length) { width_blog = $j(this).parents(".column_inner").width(); } } $j(this).width(width_blog); var $container = $j(this); var $cols = 3; if($j('.full_width').length && $j(this).parents('.grid_section').length == 0){ if($container.width() < 480) { $cols = 1; } else if($container.width() <= 703) { $cols = 2; } else if($container.width() <= 920) { $cols = 3; } else if($container.width() <= 1320) { $cols = 4; } else{ $cols = 5; } } else{ if($container.width() < 420) { $cols = 1; } else if($container.width() <= 805) { $cols = 2; } } $container.isotope({ itemSelector: 'article', resizable: false, masonry: { columnWidth: $j('.q_masonry_blog').width() / $cols } }); $j(window).resize(function(){ if($j('.full_width').length && $j(this).parents('.grid_section').length == 0){ if($container.width() < 480) { $cols = 1; } else if($container.width() <= 703) { $cols = 2; } else if($container.width() <= 920) { $cols = 3; } else if($container.width() <= 1320) { $cols = 4; } else { $cols = 5; } } else{ if($container.width() < 420) { $cols = 1; } else if($container.width() <= 785) { $cols = 2; } else { $cols = 3; } } $container.isotope({ masonry: { columnWidth: $container.width() / $cols} }); }); $j(this).animate({opacity: "1"}, 500); }); } } /* ** Init progress bar with icon */ var timeOuts = []; function initProgressBarsIcon(){ "use strict"; if($j('.q_progress_bars_icons_holder').length){ $j('.q_progress_bars_icons_holder').each(function() { var $this = $j(this); $this.appear(function() { $this.find('.q_progress_bars_icons').css('opacity','1'); $this.find('.q_progress_bars_icons').each(function() { var number = $j(this).find('.q_progress_bars_icons_inner').data('number'); var size = $j(this).find('.q_progress_bars_icons_inner').data('size'); if(size !== ""){ $j(this).find('.q_progress_bars_icons_inner.custom_size .bar').css({'width': size+'px','height':size+'px'}); $j(this).find('.q_progress_bars_icons_inner.custom_size .bar .fa-stack').css({'font-size': size/2+'px'}); } var bars = $j(this).find('.bar'); bars.each(function(i){ if(i < number){ var time = (i + 1)*150; timeOuts[i] = setTimeout(function(){ $j(bars[i]).addClass('active'); },time); } }); }); },{accX: 0, accY: -200}); }); } } (function( $ ){ "use strict"; var $window = $(window); $.fn.masonryParallax = function(speedFactor, outerHeight, startPosition) { var $this = $(this); var getHeight; var firstTop; var startPositionAdd = 0; //get the starting position of element to have parallax applied to it firstTop = $this.offset().top; //get the height element if (outerHeight) { getHeight = function(jqo) { return jqo.outerHeight(true); }; } else { getHeight = function(jqo) { return jqo.height(); }; } //get type so elements could take it's initial position if(startPosition != 0){ startPositionAdd = startPosition; } // setup defaults if arguments aren't specified if (arguments.length < 1 || speedFactor === null) speedFactor = 0.1; if (arguments.length < 2 || outerHeight === null) outerHeight = true; // function to be called whenever the window is scrolled or resized var top = $this.offset().top; var height = getHeight($this); function update(){ // Check if totally above or totally below viewport if (top + height < $scroll || top > $scroll + $window_height) { return; } $this.css('transform', 'translate3d(0px, '+ (Math.round((firstTop - height - $scroll) * speedFactor + startPositionAdd)) +'px, 0px)'); } $window.bind('scroll', update).resize(update); update(); }; })(jQuery); /** * Masonry gallery, init masonry and resize pictures in grid */ function initMasonryGallery(){ "use strict"; resizeMasonryGallery($j('.grid-sizer').width()); if($j('.masonry_gallery_holder').length){ $j('.masonry_gallery_holder').each(function(){ var $this = $j(this); $this.waitForImages(function(){ $this.animate({opacity:1}); $this.isotope({ itemSelector: '.masonry_gallery_item', masonry: { columnWidth: '.grid-sizer' } }); $this.find('.masonry_gallery_item.parallax_item').each(function(i){ $j(this).masonryParallax($this.data('parallax_item_speed'), true, $this.data('parallax_item_offset')); }); }); }); $j(window).resize(function(){ resizeMasonryGallery($j('.grid-sizer').width()); $j('.masonry_gallery_holder').isotope('reloadItems'); }); } } function resizeMasonryGallery(size){ "use strict"; var rectangle_portrait = $j('.masonry_gallery_holder .rectangle_portrait'); var rectangle_landscape = $j('.masonry_gallery_holder .rectangle_landscape'); var square_big = $j('.masonry_gallery_holder .square_big'); var square_small = $j('.masonry_gallery_holder .square_small'); rectangle_portrait.css('height', 2*size); if (window.innerWidth < 600) { rectangle_landscape.css('height', size/2); } else { rectangle_landscape.css('height', size); } square_big.css('height', 2*size); if (window.innerWidth < 600) { square_big.css('height', square_big.width()); } square_small.css('height', size); } /* ** Init more facts shortcode */ function initMoreFacts(){ "use strict"; if($j('.more_facts_holder').length){ $j('.more_facts_holder').each(function(){ var $this = $j(this); var $more_label = 'More Facts'; if($j(this).find('.more_facts_button').data('morefacts') !== ""){ $more_label = $j(this).find('.more_facts_button').data('morefacts'); } var $less_label = 'Less Facts'; if($j(this).find('.more_facts_button').data('lessfacts') !== ""){ $less_label = $j(this).find('.more_facts_button').data('lessfacts'); } var height = $this.find('.more_facts_inner').height() + 70; var speed; if(height > 0 && height < 601){ speed = 800; } else if(height > 600 && height < 1201){ speed = 1500; } else{ speed = 2100; } $this.find('.more_facts_outer').css({'height':'0px','display':'none','opacity':'0'}); $this.find('.more_facts_button').on("mouseenter",function(){ $j(this).css('color',$j(this).data('hovercolor')); }).on("mouseleave",function() { if(!$this.find('.more_facts_outer').is(':visible')){ $j(this).css('color',$j(this).data('color')); } }); $this.find('.more_facts_button').click(function(){ if(!$this.find('.more_facts_outer').is(':visible')){ $this.find('.more_facts_fake_arrow').fadeIn(speed); $this.addClass('more_fact_opened'); $j(this).parent().parent().find('.more_facts_outer').css({'display':'block','opacity':'1'}).stop().animate({'height': height+30}, speed, function() { if($j('.parallax_section_holder').length) { initParallax(); } }); $j(this).find('.more_facts_button_text').text($less_label); $j(this).find('.more_facts_button_arrow').addClass('rotate_arrow'); } else { $this.find('.more_facts_fake_arrow').fadeOut(speed); $j(this).parent().parent().find('.more_facts_outer').stop().animate({'height': '0px'}, speed,function(){ $j(this).css({'display':'none','opacity':'0'}); if(!$this.find('.more_facts_button').is(":hover")){$this.find('.more_facts_button').css('color',$this.find('.more_facts_button').data('color'));} $this.removeClass('more_fact_opened'); if($j('.parallax_section_holder').length) { initParallax(); } }); $j(this).find('.more_facts_button_text').text($more_label); $j(this).find('.more_facts_button_arrow').removeClass('rotate_arrow'); } }); }); } } /* ** Replace plceholder */ function placeholderReplace(){ "use strict"; $j('#contact-form [placeholder]').focus(function() { var input = $j(this); if (input.val() === input.attr('placeholder')) { if (this.originalType) { this.type = this.originalType; delete this.originalType; } input.val(''); input.removeClass('placeholder'); } }).blur(function() { var input = $j(this); if (input.val() === '') { if (this.type === 'password') { this.originalType = this.type; this.type = 'text'; } input.addClass('placeholder'); input.val(input.attr('placeholder')); } }).blur(); $j('#contact-form [placeholder]').parents('form').submit(function () { $j(this).find('[placeholder]').each(function () { var input = $j(this); if (input.val() === input.attr('placeholder')) { input.val(''); } }); }); } function totop_button(a) { "use strict"; var b = $j("#back_to_top"); b.removeClass("off on"); if (a === "on") { b.addClass("on"); } else { b.addClass("off"); } } function backButtonShowHide(){ "use strict"; $j(window).scroll(function () { var b = $j(this).scrollTop(); var c = $j(this).height(); var d; if (b > 0) { d = b + c / 2; } else { d = 1; } if (d < 1e3) { totop_button("off"); } else { totop_button("on"); } }); } function backToTop(){ "use strict"; $j(document).on('click','#back_to_top',function(e){ e.preventDefault(); $j('body,html').animate({scrollTop: 0}, $j(window).scrollTop()/3, 'linear'); }); } /* ** Init steps */ function initSteps(){ "use strict"; if($j('.q_steps_holder').length){ $j('.q_steps_holder').each(function(){ $j(this).appear(function() { $j(this).addClass('show'); },{accX: 0, accY: -200}); }); } } /* ** Init message height */ function initMessageHeight(){ "use strict"; if($j('.q_message.with_icon').length){ $j('.q_message.with_icon').each(function(){ if($j(this).find('.message_text_holder').height() > $j(this).find('.q_message_icon_holder').height()) { $j(this).find('.q_message_icon_holder').height($j(this).find('.message_text').height()); } else { $j(this).find('.message_text').height($j(this).find('.q_message_icon_holder').height()); } }); } } /** * Init image hover */ function initImageHover() { "use strict"; if($j('.image_hover').length){ $j('.image_hover').each(function(){ $j(this).appear(function() { var default_visible_time = 300; var transition_delay = $j(this).attr('data-transition-delay'); var real_transition_delay = default_visible_time + parseFloat(transition_delay); var object = $j(this); //wait for other hovers to complete setTimeout(function() { object.addClass('show'); }, parseFloat(transition_delay)); //hold that image a little, than remove class setTimeout(function() { object.removeClass('show'); }, real_transition_delay); },{accX: 0, accY: -200}); }); } } /* * Initializes vertical progress bars */ function initProgressBarsVertical(){ "use strict"; if($j('.q_progress_bars_vertical').length){ $j('.q_progress_bars_vertical').each(function() { $j(this).appear(function() { initToCounterVerticalProgressBar($j(this)); var percentage = $j(this).find('.progress_content').data('percentage'); $j(this).find('.progress_content').css('height', '0%'); $j(this).find('.progress_content').animate({ height: percentage+'%' }, 1500); },{accX: 0, accY: -200}); }); } } /* * Initializes vertical progress bar count to max value */ function initToCounterVerticalProgressBar($this){ "use strict"; if($this.find('.progress_number span').length){ $this.find('.progress_number span').each(function() { var $max = parseFloat($j(this).text()); $j(this).countTo({ from: 0, to: $max, speed: 1500, refreshInterval: 50 }); }); } } /* * Check if there is anchor on load and scroll to it */ function checkAnchorOnLoad(){ "use strict"; var hash = window.location.hash; var paspartuScrollAdd = $j('body').hasClass('paspartu_on_top_fixed') ? $window_width*paspartu_width : 0; var scrollToAmount; var top_header_height; if(hash !== "" && $j('[data-q_id="'+hash+'"]').length > 0){ if($j('header.page_header').hasClass('fixed') && !$j('body').hasClass('vertical_menu_enabled')){ if($j('header.page_header').hasClass('scroll_top')){ top_header_height = header_top_height; }else{ top_header_height = 0; } if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { if(header_height - ($j('[data-q_id="' + hash + '"]').offset().top + top_header_height)/4 >= min_header_height_scroll){ var diff_of_header_and_section = $j('[data-q_id="' + hash + '"]').offset().top - header_height - paspartuScrollAdd; scrollToAmount = diff_of_header_and_section + (diff_of_header_and_section/4) + (diff_of_header_and_section/16) + (diff_of_header_and_section/64) + 1; //several times od dividing to minimize the error, because fixed header is shrinking while scroll, 1 is just to ensure }else{ if($j('header.page_header').hasClass('centered_logo')){ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_scroll - logo_height - 30 - paspartuScrollAdd; //30 is top/bottom margin of logo } else { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_scroll - paspartuScrollAdd; } } }else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } } else if($j('header.page_header').hasClass('fixed_top_header') && !$j('body').hasClass('vertical_menu_enabled')){ if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')){ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - header_top_height - paspartuScrollAdd; }else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } } else if($j('header.page_header').hasClass('fixed_hiding') && !$j('body').hasClass('vertical_menu_enabled')){ if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { if ($j('[data-q_id="' + hash + '"]').offset().top - (header_height + logo_height / 2 + 40) <= scroll_amount_for_fixed_hiding) { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - header_height - logo_height / 2 - 40 - paspartuScrollAdd; //40 is top/bottom margin of logo } else { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_fixed_hidden - 40 - paspartuScrollAdd; //40 is top/bottom margin of logo } }else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } }else if($j('header.page_header').hasClass('stick') || $j('header.page_header').hasClass('stick_with_left_right_menu') && !$j('body').hasClass('vertical_menu_enabled')) { if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { if (sticky_amount >= $j('[data-q_id="' + hash + '"]').offset().top) { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top + 1 - paspartuScrollAdd; // 1 is to show sticky menu } else { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_sticky - paspartuScrollAdd; } }else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } } else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } $j('html, body').animate({ scrollTop: Math.round(scrollToAmount) }, 1500, function() {}); } //remove active state on anchors if section is not visible $j(".main_menu a, .vertical_menu a, .mobile_menu a").each(function(){ var i = $j(this).prop("hash"); if(i !== "" && ($j('[data-q_id="' + i + '"]').length > 0) && ($j('[data-q_id="' + i + '"]').offset().top >= $window_height) && $scroll === 0){ $j(this).parent().removeClass('active'); $j(this).removeClass('current'); } }); } /* * Check active state of anchor links on scroll */ function changeActiveState(id){ "use strict"; $j('.main_menu a').parent().removeClass('active'); $j(".main_menu a").each(function(){ var i = $j(this).prop("hash"); if(i === id){ if($j(this).closest('.second').length === 0){ $j(this).parent().addClass('active'); }else{ $j(this).closest('.second').parent().addClass('active'); } $j('.main_menu a').removeClass('current'); $j(this).addClass('current'); } }); $j('.vertical_menu a').parent().removeClass('active'); $j(".vertical_menu a").each(function(){ var i = $j(this).prop("hash"); if(i === id){ if($j(this).closest('.second').length === 0){ $j(this).parent().addClass('active'); }else{ $j(this).closest('.second').parent().addClass('active'); } $j('.vertical_menu a').removeClass('current'); $j(this).addClass('current'); } }); $j('.mobile_menu a').parent().removeClass('active'); $j(".mobile_menu a").each(function(){ var i = $j(this).prop("hash"); if(i === id){ if($j(this).closest('.sub_menu').length === 0){ $j(this).parent().addClass('active'); }else{ $j(this).closest('.sub_menu').parent().addClass('active'); } $j('.mobile_menu a').removeClass('current'); $j(this).addClass('current'); } }); } /* * Check active state of anchor links on scroll */ function checkAnchorOnScroll(){ "use strict"; if($j('[data-q_id]').length && !$j('header.page_header').hasClass('regular')){ $j('[data-q_id]').waypoint( function(direction) { if(direction === 'down') { changeActiveState($j(this).data("q_id")); } }, { offset: '50%' }); $j('[data-q_id]').waypoint( function(direction) { if(direction === 'up') { changeActiveState($j(this).data("q_id")); } }, { offset: function(){ return -($j(this).outerHeight() - 150); } }); } } /* * Init scroll to section link if that link has hash value */ function initHashClick(){ "use strict"; var $doc = $j('html, body'); var paspartuScrollAdd = $j('body').hasClass('paspartu_on_top_fixed') ? $window_width*paspartu_width : 0; var scrollToAmount; $j(document).on( "click", ".main_menu a, .vertical_menu a, .qbutton:not(.contact_form_button), .anchor, .widget li.anchor a", function(){ var $this = $j(this); var hash = $j(this).prop("hash"); var top_header_height; if((hash !== "" && $j(this).attr('href').split('#')[0] === "") || (hash !== "" && $j(this).attr('href').split('#')[0] !== "" && hash === window.location.hash) || (hash !== "" && $j(this).attr('href').split('#')[0] === window.location.href.split('#')[0])){ //in third condition 'hash !== ""' stays to prevent reload of page when link is active and ajax enabled if($j('header.page_header').hasClass('fixed') && !$j('body').hasClass('vertical_menu_enabled')){ if($j('header.page_header').hasClass('scroll_top')){ top_header_height = header_top_height; }else{ top_header_height = 0; } if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { if (header_height - ($j('[data-q_id="' + hash + '"]').offset().top + top_header_height) / 4 >= min_header_height_scroll) { var diff_of_header_and_section = $j('[data-q_id="' + hash + '"]').offset().top - header_height - paspartuScrollAdd; scrollToAmount = diff_of_header_and_section + (diff_of_header_and_section / 4) + (diff_of_header_and_section / 16) + (diff_of_header_and_section / 64) + 1; //several times od dividing to minimize the error, because fixed header is shrinking while scroll, 1 is just to ensure } else { if($j('header.page_header').hasClass('centered_logo')){ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_scroll - logo_height - paspartuScrollAdd - 30; //30 is top/bottom margin of logo } else { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_scroll - paspartuScrollAdd; } } }else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } } else if($j('header.page_header').hasClass('fixed_top_header') && !$j('body').hasClass('vertical_menu_enabled')){ if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')){ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - header_top_height - paspartuScrollAdd; }else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } } else if($j('header.page_header').hasClass('fixed_hiding') && !$j('body').hasClass('vertical_menu_enabled')){ if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { if ($j('[data-q_id="' + hash + '"]').offset().top - (header_height + logo_height / 2 + 40) <= scroll_amount_for_fixed_hiding) { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - header_height - logo_height / 2 - 40 - paspartuScrollAdd; //40 is top/bottom margin of logo } else { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_fixed_hidden - 40 - paspartuScrollAdd; //40 is top/bottom margin of logo } }else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } }else if($j('header.page_header').hasClass('stick') || $j('header.page_header').hasClass('stick_with_left_right_menu') && !$j('body').hasClass('vertical_menu_enabled')) { if(!$j('header.page_header').hasClass('transparent') || $j('header.page_header').hasClass('scrolled_not_transparent')) { if (sticky_amount >= $j('[data-q_id="' + hash + '"]').offset().top) { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top + 1 - paspartuScrollAdd; // 1 is to show sticky menu } else { scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - min_header_height_sticky - paspartuScrollAdd; } }else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } } else{ scrollToAmount = $j('[data-q_id="' + hash + '"]').offset().top - paspartuScrollAdd; } if($j('[data-q_id="'+hash+'"]').length > 0){ $doc.stop().animate({ scrollTop: Math.round(scrollToAmount) }, 1500, function() { anchorActiveState($this); }); } if(history.pushState) { history.pushState(null, null, hash); } return false; } }); $j(document).on( "click", ".mobile_menu a", function(){ var $this = $j(this); var hash = $j(this).prop("hash"); if((hash !== "" && $j(this).attr('href').split('#')[0] === "") || (hash !== "" && $j(this).attr('href').split('#')[0] !== "" && hash === window.location.hash) || (hash !== "" && $j(this).attr('href').split('#')[0] === window.location.href.split('#')[0])){ //in third condition 'hash !== ""' stays to prevent reload of page when link is active and ajax enabled if($j('[data-q_id="'+hash+'"]').length > 0){ $doc.animate({ scrollTop: Math.round($j('[data-q_id="'+hash+'"]').offset().top - $j('.mobile_menu').height()) }, 500,function(){ anchorActiveState($this); }); } if(history.pushState) { history.pushState(null, null, hash); } return false; } }); } /* ** Add class to items in last row in clients shortcode */ function countClientsPerRow(){ "use strict"; if($j('.qode_clients').length){ $j('.qode_clients').each(function() { var $clients = $j(this); var qode_clients_height = $clients.height(); var qode_clients_width = $clients.width(); var maxHeightClient; var clientWidth = $clients.find('.qode_client_holder').width(); var countClient = $clients.find('.qode_client_holder').length; $clients.find('.qode_client_holder').each(function() { maxHeightClient = maxHeightClient > $j(this).height() ? maxHeightClient : $j(this).height(); }); maxHeightClient = maxHeightClient + 35; //margin for client is 35 var numberOfRows = Math.ceil(qode_clients_height / maxHeightClient); var numberOfClientsPerRow = Math.ceil(qode_clients_width/clientWidth); var numberOffullRows = Math.floor(countClient / numberOfClientsPerRow); var numberOfClientsInLastRow = countClient - (numberOfClientsPerRow * numberOffullRows); if(numberOfClientsInLastRow === 0){ numberOfClientsInLastRow = numberOfClientsPerRow; } $clients.find( ".qode_client_holder" ).removeClass('border-bottom-none'); var item_start_from = countClient - numberOfClientsInLastRow - 1; $clients.find( ".qode_client_holder:gt("+ item_start_from +")" ).addClass('border-bottom-none'); }); } } /* ** Calculate height for animated text icon shortcode */ function animatedTextIconHeight(){ "use strict"; if($j('.animated_icons_with_text').length){ var $icons = $j('.animated_icons_with_text'); var maxHeight; $icons.find('.animated_text p').each(function() { maxHeight = maxHeight > $j(this).height() ? maxHeight : $j(this).height(); }); if(maxHeight < 155) { maxHeight = 155; } $icons.find('.animated_icon_with_text_inner').height(maxHeight); } } /* ** Add class to items in last row in animated text icon shortcode */ function countAnimatedTextIconPerRow(){ "use strict"; if($j('.animated_icons_with_text').length){ $j('.animated_icons_with_text').each(function() { var $icons = $j(this); var qode_icons_height = $icons.height(); var qode_icons_width = $icons.width(); var maxHeightIcons; var iconWidth = $icons.find('.animated_icon_with_text_holder').width() + 1; // 1px because safari round on smaller number var countIcons = $icons.find('.animated_icon_with_text_holder').length; $icons.find('.animated_icon_with_text_holder').each(function() { maxHeightIcons = maxHeightIcons > $j(this).height() ? maxHeightIcons : $j(this).height(); }); maxHeightIcons = maxHeightIcons + 30; //margin for client is 30 var numberOfIconsPerRow = Math.ceil((qode_icons_width/iconWidth)); var numberOffullRows = Math.floor(countIcons / numberOfIconsPerRow); var numberOfIconsInLastRow = countIcons - (numberOfIconsPerRow * numberOffullRows); if(numberOfIconsInLastRow === 0){ numberOfIconsInLastRow = numberOfIconsPerRow; } $icons.find( ".animated_icon_with_text_holder" ).removeClass('border-bottom-none'); var item_start_from = countIcons - numberOfIconsInLastRow - 1; $icons.find( ".animated_icon_with_text_holder:gt("+ item_start_from +")" ).addClass('border-bottom-none'); }); } } /* * Set active state in maim menu on anchor click */ function anchorActiveState(me){ if(me.closest('.main_menu').length > 0){ $j('.main_menu a').parent().removeClass('active'); } if(me.closest('.vertical_menu').length > 0){ $j('.vertical_menu a').parent().removeClass('active'); } if(me.closest('.second').length === 0){ me.parent().addClass('active'); }else{ me.closest('.second').parent().addClass('active'); } if(me.closest('.mobile_menu').length > 0){ $j('.mobile_menu a').parent().removeClass('active'); me.parent().addClass('active'); } $j('.mobile_menu a, .main_menu a, .vertical_menu a').removeClass('current'); me.addClass('current'); } /* ** Video background initialization */ function initVideoBackground(){ "use strict"; $j('.video-wrap .video').mediaelementplayer({ enableKeyboard: false, iPadUseNativeControls: false, pauseOtherPlayers: false, // force iPhone's native controls iPhoneUseNativeControls: false, // force Android's native controls AndroidUseNativeControls: false }); //mobile check if(navigator.userAgent.match(/(Android|iPod|iPhone|iPad|IEMobile|Opera Mini)/)){ initVideoBackgroundSize(); $j('.mobile-video-image').show(); $j('.video-wrap').remove(); } } /* ** Calculate video background size */ function initVideoBackgroundSize(){ "use strict"; $j('.section .video-wrap').each(function(i){ var $sectionWidth = $j(this).closest('.section').outerWidth(); $j(this).width($sectionWidth); var $sectionHeight = $j(this).closest('.section').outerHeight(); min_w = vid_ratio * ($sectionHeight+20); $j(this).height($sectionHeight); var scale_h = $sectionWidth / video_width_original; var scale_v = ($sectionHeight - header_height) / video_height_original; var scale = scale_v; if (scale_h > scale_v) scale = scale_h; if (scale * video_width_original < min_w) {scale = min_w / video_width_original;} $j(this).find('video, .mejs-overlay, .mejs-poster').width(Math.ceil(scale * video_width_original +2)); $j(this).find('video, .mejs-overlay, .mejs-poster').height(Math.ceil(scale * video_height_original +2)); $j(this).scrollLeft(($j(this).find('video').width() - $sectionWidth) / 2); $j(this).find('.mejs-overlay, .mejs-poster').scrollTop(($j(this).find('video').height() - ($sectionHeight)) / 2); $j(this).scrollTop(($j(this).find('video').height() - ($sectionHeight)) / 2); }); $j('.carousel .item .video .video-wrap').each(function(i){ var $slideWidth = $j(window).width(); $j(this).width($slideWidth); var mob_header = $j(window).width() < 1000 ? $j('header.page_header').height() - 6 : 0; // 6 is because of the display: inline-block var $slideHeight = $j(this).closest('.carousel.slide').height() - mob_header; min_w = vid_ratio * ($slideHeight+20); $j(this).height($slideHeight); var scale_h = $slideWidth / video_width_original; var scale_v = ($slideHeight - header_height) / video_height_original; var scale = scale_v; if (scale_h > scale_v) scale = scale_h; if (scale * video_width_original < min_w) {scale = min_w / video_width_original;} $j(this).find('video, .mejs-overlay, .mejs-poster').width(Math.ceil(scale * video_width_original +2)); $j(this).find('video, .mejs-overlay, .mejs-poster').height(Math.ceil(scale * video_height_original +2)); $j(this).scrollLeft(($j(this).find('video').width() - $slideWidth) / 2); $j(this).find('.mejs-overlay, .mejs-poster').scrollTop(($j(this).find('video').height() - ($slideHeight)) / 2); $j(this).scrollTop(($j(this).find('video').height() - ($slideHeight)) / 2); }); $j('.portfolio_single .video .video-wrap, .blog_holder .video .video-wrap').each(function(i){ var $this = $j(this); var $videoWidth = $j(this).closest('.video').outerWidth(); $j(this).width($videoWidth); var $videoHeight = ($videoWidth*9)/16; if(navigator.userAgent.match(/(Android|iPod|iPhone|iPad|IEMobile|Opera Mini)/)){ $this.parent().width($videoWidth); $this.parent().height($videoHeight); } min_w = vid_ratio * ($videoHeight+20); $j(this).height($videoHeight); var scale_h = $videoWidth / video_width_original; var scale_v = ($videoHeight - header_height) / video_height_original; var scale = scale_v; if (scale_h > scale_v) scale = scale_h; if (scale * video_width_original < min_w) {scale = min_w / video_width_original;} $j(this).find('video, .mejs-overlay, .mejs-poster').width(Math.ceil(scale * video_width_original +2)); $j(this).find('video, .mejs-overlay, .mejs-poster').height(Math.ceil(scale * video_height_original +2)); $j(this).scrollLeft(($j(this).find('video').width() - $videoWidth) / 2); $j(this).find('.mejs-overlay, .mejs-poster').scrollTop(($j(this).find('video').height() - ($videoHeight)) / 2); $j(this).scrollTop(($j(this).find('video').height() - ($videoHeight)) / 2); }); } /* ** Icon With Text animation effect */ function initIconWithTextAnimation(){ "use strict"; if($j('.q_icon_animation').length > 0 && $j('.no_animation_on_touch').length === 0){ $j('.q_icon_animation').each(function(){ $j(this).appear(function() { $j(this).addClass('q_show_animation'); },{accX: 0, accY: -200}); }); } } /* ** Add class on body if browser is Safari */ function initCheckSafariBrowser(){ "use strict"; if (navigator.userAgent.indexOf('Safari') !== -1 && navigator.userAgent.indexOf('Chrome') === -1) { $j('body').addClass('safari_browser'); } } /* ** Initialize Qode search form */ function initSearchButton(){ if($j('.search_slides_from_window_top').length){ $j('.search_slides_from_window_top').click(function(e){ e.preventDefault(); if($j('html').hasClass('touch')){ if ($j('.qode_search_form').height() == "0") { $j('.qode_search_form input[type="text"]').onfocus = function () { window.scrollTo(0, 0); document.body.scrollTop = 0; }; $j('.qode_search_form input[type="text"]').onclick = function () { window.scrollTo(0, 0); document.body.scrollTop = 0; }; $j('.header_top_bottom_holder').css('top','50px'); $j('.qode_search_form').css('height','50px'); $j('.content_inner').css('margin-top','50px'); if($scroll < 34){ $j('header.page_header').css('top','0'); } } else { $j('.qode_search_form').css('height','0'); $j('.header_top_bottom_holder').css('top','0'); $j('.content_inner').css('margin-top','0'); if($scroll < 34){ $j('header.page_header').css('top',-$scroll);} } $j(window).scroll(function() { if ($j('.qode_search_form').height() != "0" && $scroll > 50) { $j('.qode_search_form').css('height','0'); $j('.header_top_bottom_holder').css('top','0'); $j('.content_inner').css('margin-top','0'); } }); $j('.qode_search_close').click(function(e){ e.preventDefault(); $j('.qode_search_form').css('height','0'); $j('.header_top_bottom_holder').css('top','0'); $j('.content_inner').css('margin-top','0'); if($scroll < 34){ $j('header.page_header').css('top',-$scroll);} }); } else { if($j('.title').hasClass('has_fixed_background')){ var yPos = parseInt($j('.title.has_fixed_background').css('backgroundPosition').split(" ")[1]); }else { var yPos = 0; } if ($j('.qode_search_form').height() == "0") { $j('.qode_search_form input[type="text"]').focus(); $j('.header_top_bottom_holder').stop().animate({top:"50px"},150); $j('.qode_search_form').stop().animate({height:"50px"},150); $j('.content_inner').stop().animate({marginTop:"50px"},150); if($scroll < 34){ $j('header.page_header').stop().animate({top:0},150); } $j('.title.has_fixed_background').animate({ 'background-position-y': (yPos + 50)+'px' }, 150); } else { $j('.qode_search_form').stop().animate({height:"0"},150); $j('.header_top_bottom_holder').stop().animate({top:"0px"},150); $j('.content_inner').stop().animate({marginTop:"0"},150); if($scroll < 34){ $j('header.page_header').stop().animate({top:-$scroll},150);} $j('.title.has_fixed_background').animate({ 'background-position-y': (yPos - 50)+'px' }, 150); } $j(window).scroll(function() { if ($j('.qode_search_form').height() != "0" && $scroll > 50) { $j('.qode_search_form').stop().animate({height:"0"},150); $j('.header_top_bottom_holder').stop().animate({top:"0px"},150); $j('.content_inner').stop().animate({marginTop:"0"},150); $j('.title.has_fixed_background').css('backgroundPosition', 'center '+(yPos)+'px'); } }); $j('.qode_search_close').click(function(e){ e.preventDefault(); $j('.qode_search_form').stop().animate({height:"0"},150); $j('.content_inner').stop().animate({marginTop:"0"},150); $j('.header_top_bottom_holder').stop().animate({top:"0px"},150); if($scroll < 34){ $j('header.page_header').stop().animate({top:-$scroll},150);} $j('.title.has_fixed_background').animate({ 'background-position-y': (yPos)+'px' }, 150); }); } }); } //search type - search_slides_from_header_bottom if($j('.search_slides_from_header_bottom').length){ $j('.search_slides_from_header_bottom').click(function(e){ e.preventDefault(); if($j('html').hasClass('touch')){ if ($j('.qode_search_form_2').height() == "0") { $j('.qode_search_form_2 input[type="text"]').onfocus = function () { window.scrollTo(0, 0); document.body.scrollTop = 0; }; $j('.qode_search_form_2 input[type="text"]').onclick = function () { window.scrollTo(0, 0); document.body.scrollTop = 0; }; $j('.qode_search_form_2').css('height','50px'); } else { $j('.qode_search_form_2').css('height','0'); } $j(window).scroll(function() { if ($j('.qode_search_form_2').height() != "0" && $scroll > 50) { $j('.qode_search_form_2').css('height','0'); } }); } else { if($j('.qode_search_form_2').hasClass('animated')) { $j('.qode_search_form_2').removeClass('animated'); $j('.qode_search_form_2').css('bottom','0'); } else { $j('.qode_search_form input[type="text"]').focus(); $j('.qode_search_form_2').addClass('animated'); var search_form_height = $j('.qode_search_form_2').height(); $j('.qode_search_form_2').css('bottom',-search_form_height); } $j('.qode_search_form_2').addClass('disabled'); $j('.qode_search_form_2 input[type="submit"]').attr('disabled','disabled'); if(($j('.qode_search_form_2 .qode_search_field').val() !== '') && ($j('.qode_search_form_2 .qode_search_field').val() !== ' ')) { $j('.qode_search_form_2 input[type="submit"]').removeAttr('disabled'); $j('.qode_search_form_2').removeClass('disabled'); } else { $j('.qode_search_form_2').addClass('disabled'); $j('.qode_search_form_2 input[type="submit"]').attr('disabled','disabled'); } $j('.qode_search_form_2 .qode_search_field').keyup(function() { if(($j(this).val() !== '') && ($j(this).val() != ' ')) { $j('.qode_search_form_2 input[type="submit"]').removeAttr('disabled'); $j('.qode_search_form_2').removeClass('disabled'); } else { $j('.qode_search_form_2 input[type="submit"]').attr('disabled','disabled'); $j('.qode_search_form_2').addClass('disabled'); } }); $j('.content, footer').click(function(e){ e.preventDefault(); $j('.qode_search_form_2').removeClass('animated'); $j('.qode_search_form_2').css('bottom','0'); }); } }); } //search type - search covers header if($j('.search_covers_header').length){ $j('.search_covers_header').click(function(e){ e.preventDefault(); if($j(".search_covers_only_bottom").length){ var headerHeight = $j('.header_bottom').height(); } else{ if($j(".fixed_top_header").length){ var headerHeight = $j('.top_header').height(); }else{ var headerHeight = $j('.header_top_bottom_holder').height(); } } $j('.qode_search_form_3 .form_holder_outer').height(headerHeight); if($j(".search_covers_only_bottom").length){ $j('.qode_search_form_3').css('bottom',0); $j('.qode_search_form_3').css('top','auto'); } $j('.qode_search_form_3').stop(true).fadeIn(600,'easeOutExpo'); $j('.qode_search_form_3 input[type="text"]').focus(); $j(window).scroll(function() { if($j(".search_covers_only_bottom").length){ var headerHeight = $j('.header_bottom').height(); } else{ if($j(".fixed_top_header").length){ var headerHeight = $j('.top_header').height(); }else{ var headerHeight = $j('.header_top_bottom_holder').height(); } } $j('.qode_search_form_3 .form_holder_outer').height(headerHeight); }); $j('.qode_search_close, .content, footer').click(function(e){ e.preventDefault(); $j('.qode_search_form_3').stop(true).fadeOut(450,'easeOutExpo'); }); $j('.qode_search_form_3').blur(function(e){ $j('.qode_search_form_3').stop(true).fadeOut(450,'easeOutExpo'); }); }); } //search type - fullscreen search if($j('.fullscreen_search').length){ //search type Circle Appear if($j(".fullscreen_search_holder.from_circle").length){ $j('.fullscreen_search').on('click',function(e){ e.preventDefault(); if($j('.fullscreen_search_overlay').hasClass('animate')){ $j('.fullscreen_search_overlay').removeClass('animate'); $j('.fullscreen_search_holder').css('opacity','0'); $j('.fullscreen_search_close').css('opacity','0'); $j('.fullscreen_search_close').css('visibility','hidden'); $j('.fullscreen_search').css('opacity','1'); $j('.fullscreen_search_holder').css('display','none'); } else { $j('.fullscreen_search_overlay').addClass('animate'); $j('.fullscreen_search_holder').css('display','block'); setTimeout(function(){ $j('.fullscreen_search_holder').css('opacity','1'); $j('.fullscreen_search_close').css('opacity','1'); $j('.fullscreen_search_close').css('visibility','visible'); $j('.fullscreen_search').css('opacity','0'); },200); } }); $j('.fullscreen_search_close').on('click',function(e){ e.preventDefault(); $j('.fullscreen_search_overlay').removeClass('animate'); $j('.fullscreen_search_holder').css('opacity','0'); $j('.fullscreen_search_close').css('opacity','0'); $j('.fullscreen_search_close').css('visibility','hidden'); $j('.fullscreen_search').css('opacity','1'); $j('.fullscreen_search_holder').css('display','none'); }); } //search type Fade Appear if($j(".fullscreen_search_holder.fade").length){ $j('.fullscreen_search').on('click',function(e){ e.preventDefault(); if($j('.fullscreen_search_holder').hasClass('animate')) { $j('body').removeClass('fullscreen_search_opened'); $j('.fullscreen_search_holder').removeClass('animate'); $j('body').removeClass('search_fade_out'); $j('body').removeClass('search_fade_in'); } else { $j('body').addClass('fullscreen_search_opened'); $j('body').removeClass('search_fade_out'); $j('body').addClass('search_fade_in'); $j('.fullscreen_search_holder').addClass('animate'); } }); $j('.fullscreen_search_close').on('click',function(e){ e.preventDefault(); $j('body').removeClass('fullscreen_search_opened'); $j('.fullscreen_search_holder').removeClass('animate'); $j('body').removeClass('search_fade_in'); $j('body').addClass('search_fade_out'); }); } //Text input focus change $j('.fullscreen_search_holder .search_field').focus(function(){ $j('.fullscreen_search_holder .field_holder .line').css("width","100%"); }); $j('.fullscreen_search_holder .search_field').blur(function(){ $j('.fullscreen_search_holder .field_holder .line').css("width","0"); }); //search close button - setting its position vertically $j(window).scroll(function() { var bottom_height = $j(".page_header .header_bottom").height(); if($j(".page_header").hasClass("sticky")){ $j(".fullscreen_search_holder .side_menu_button").css("height",bottom_height); $j(".fullscreen_search_holder .close_container").css("top","0"); } else if($j(".page_header").hasClass("fixed")){ $j(".fullscreen_search_holder .side_menu_button").css("height",bottom_height); } else { $j(".fullscreen_search_holder .side_menu_button").css("height",""); $j(".fullscreen_search_holder .close_container").css("top",""); } }); } if($j('.qode_search_submit').length) { $j('.qode_search_submit').click(function(e) { e.preventDefault(); e.stopPropagation(); var searchForm = $j(this).parents('form').first(); searchForm.submit(); }); } } /* ** Init update Shopping Cart */ function updateShoppingCart(){ "use strict"; $j('body').bind('added_to_cart', add_to_cart); function add_to_cart(event, parts, hash) { var miniCart = $j('.shopping_cart_header'); if ( parts['div.widget_shopping_cart_content'] ) { var $cartContent = jQuery(parts['div.widget_shopping_cart_content']), $itemsList = $cartContent .find('.cart_list'), $total = $cartContent.find('.total').contents(':not(strong)').text(); miniCart.find('.shopping_cart_dropdown_inner').html('').append($itemsList); miniCart.find('.total span').html('').append($total); } } } /* ** Set content bottom margin because of the uncovering footer */ function setContentBottomMargin(){ if($j('.uncover').length){ $j('.content').css('margin-bottom', $j('footer').height()); } } /* ** Set footer uncover with vertical area */ function footerWidth(){ "use strict"; if($j('.uncover').length && $j('body').hasClass('vertical_menu_enabled') && $window_width > 1000){ $j('.uncover').width($window_width - $j('.vertical_menu_area').width()); } else{ $j('.uncover').css('width','100%'); } } /* ** Boxes which reveal text on hover */ function initCoverBoxes(){ if($j('.cover_boxes').length) { $j('.cover_boxes').each(function(){ var active_element = 0; var data_active_element = 1; if(typeof $j(this).data('active-element') !== 'undefined' && $j(this).data('active-element') !== false) { data_active_element = parseFloat($j(this).data('active-element')); active_element = data_active_element - 1; } var number_of_columns = 3; //validate active element active_element = data_active_element > number_of_columns ? 0 : active_element; $j(this).find('li').eq(active_element).addClass('act'); var cover_boxed = $j(this); $j(this).find('li').each(function(){ $j(this).hover(function() { $j(cover_boxed).find('li').removeClass('act'); $j(this).addClass('act'); }); }); }); } } /* ** Create content menu from selected rows */ function createContentMenu(){ "use strict"; var content_menu = $j(".content_menu"); content_menu.each(function(){ if($j(this).find('ul').length === 0){ if($j(this).css('background-color') !== ""){ var background_color = $j(this).css('background-color'); } var content_menu_ul = $j(""); content_menu_ul.appendTo($j(this)); var sections = $j(this).siblings('.in_content_menu'); if(sections.length){ sections.each(function(){ var section_href = $j(this).data("q_id"); var section_title = $j(this).data('q_title'); var section_icon = $j(this).data('q_icon'); var li = $j("
  • "); var icon = $j("", {"class": 'fa '+section_icon}); var link = $j("", {"href": section_href, "html": "" + section_title + ""}); var arrow; if(background_color !== ""){ arrow = $j("
    ", {"class": 'arrow', "style": 'border-color: '+background_color+' transparent transparent transparent'}); } else { arrow = $j("
    ", {"class": 'arrow'}); } icon.prependTo(link); link.appendTo(li); arrow.appendTo(li); li.appendTo(content_menu_ul); }); } } }); } /* ** Create content menu (select menu for responsiveness)from selected rows */ function createSelectContentMenu(){ "use strict"; var content_menu = $j(".content_menu"); content_menu.each(function(){ var $this = $j(this); var $menu_select = $j("
      "); $menu_select.appendTo($j(this).find('.nav_select_menu')); $j(this).find("ul.menu li a").each(function(){ var menu_url = $j(this).attr("href"); var menu_text = $j(this).text(); var menu_icon = $j(this).find('i').clone(); if ($j(this).parents("li").length === 2) { menu_text = "   " + menu_text; } if ($j(this).parents("li").length === 3) { menu_text = "      " + menu_text; } if ($j(this).parents("li").length > 3) { menu_text = "         " + menu_text; } var li = $j("
    • "); var link = $j("", {"href": menu_url, "html": menu_text}); menu_icon.prependTo(link); link.appendTo(li); li.appendTo($menu_select); }); $this.find(".nav_select_button").on('click', function() { if ($this.find('.nav_select_menu ul').is(":visible")){ $this.find('.nav_select_menu ul').slideUp(); } else { $this.find('.nav_select_menu ul').slideDown(); } return false; }); $this.find(".nav_select_menu ul li a").on('click',function () { $this.find('.nav_select_menu ul').slideUp(); var $link = $j(this); var $target = $link.attr("href"); var targetOffset = $j("div.wpb_row[data-q_id='" + $target + "'],section.parallax_section_holder[data-q_id='" + $target + "']").offset().top; $j('html,body').stop().animate({scrollTop: targetOffset }, 500, 'swing', function(){ $j('nav.content_menu ul li').removeClass('active'); $link.parent().addClass('active'); }); return false; }); }); } /* ** Calculate content menu position and fix it when needed */ function contentMenuPosition(){ "use strict"; if($j('nav.content_menu').length){ if(content_menu_position > sticky_amount){ var x = min_header_height_sticky; }else{ var x = 0; } if(content_menu_position - x - content_menu_top_add - $scroll <= 0 && ($j('header').hasClass('stick') || $j('header').hasClass('stick_with_left_right_menu'))){ if(content_menu_position < sticky_amount){ if($scroll > sticky_amount){ $j('nav.content_menu').css({'position': 'fixed', 'top': min_header_height_sticky + content_menu_top_add}).addClass('fixed'); }else{ $j('nav.content_menu').css({'position': 'fixed', 'top': 0, transition:'none'}).addClass('fixed'); } }else{ $j('nav.content_menu').css({'position': 'fixed', 'top': min_header_height_sticky + content_menu_top_add}).addClass('fixed'); } $j('header.sticky').addClass('no_shadow'); $j('.content > .content_inner > .container > .container_inner').css('margin-top',content_line_height); $j('.content > .content_inner > .full_width').css('margin-top',content_line_height); } else if(content_menu_position - content_menu_top - content_menu_top_add - $scroll <= 0 && !($j('header').hasClass('stick'))) { $j('nav.content_menu').css({'position': 'fixed', 'top': content_menu_top + content_menu_top_add}).addClass('fixed'); $j('.content > .content_inner > .container > .container_inner').css('margin-top',content_line_height); $j('.content > .content_inner > .full_width').css('margin-top',content_line_height); } else { $j('nav.content_menu').css({'position': 'relative', 'top': '0px'}).removeClass('fixed'); $j('header.sticky').removeClass('no_shadow'); $j('.content > .content_inner > .container > .container_inner').css('margin-top','0px'); $j('.content > .content_inner > .full_width').css('margin-top','0px'); } $j('.content .in_content_menu').waypoint( function(direction) { var $active = $j(this); var id = $active.data("q_id"); $j("nav.content_menu.fixed li a").each(function(){ var i = $j(this).attr("href"); if(i === id){ $j(this).parent().addClass('active'); }else{ $j(this).parent().removeClass('active'); } }); }, { offset: '150' }); } } /* ** Check first and last content menu included rows for active state in content menu */ function contentMenuCheckLastSection(){ "use strict"; if($j('nav.content_menu').length){ if($j('.content .in_content_menu').length){ var last_from_top = $j('.content .in_content_menu:last').offset().top + $j('.content .in_content_menu:last').height(); var first_from_top = $j('.content .in_content_menu:first').offset().top - content_menu_top - content_menu_top_add - 100; //60 is height of content menu if(last_from_top < $scroll){ $j("nav.content_menu.fixed li").removeClass('active'); } if(first_from_top > $scroll){ $j('nav.content_menu li:first, nav.content_menu ul.menu li:first').removeClass('active'); } } } } /* ** Scroll to section when item in content menu is clicked */ function contentMenuScrollTo(){ "use strict"; if($j('nav.content_menu').length){ $j("nav.content_menu ul.menu li a").on('click', function(e){ e.preventDefault(); var $this = $j(this); if($j(this).parent().hasClass('active')){ return false; } var $target = $this.attr("href"); var targetOffset = $j("div.wpb_row[data-q_id='" + $target + "'],section.parallax_section_holder[data-q_id='" + $target + "']").offset().top - content_line_height - content_menu_top - content_menu_top_add; $j('html,body').stop().animate({scrollTop: targetOffset }, 500, 'swing', function(){ $j('nav.content_menu ul li').removeClass('active'); $this.parent().addClass('active'); }); return false; }); } } function initButtonHover() { if($j('.qbutton').length) { $j('.qbutton').each(function() { //hover background color if(typeof $j(this).data('hover-background-color') !== 'undefined' && $j(this).data('hover-background-color') !== false) { var hover_background_color = $j(this).data('hover-background-color'); var initial_background_color = $j(this).css('background-color'); $j(this).hover( function() { $j(this).css('background-color', hover_background_color); }, function() { $j(this).css('background-color', initial_background_color); }); } //hover border color if(typeof $j(this).data('hover-border-color') !== 'undefined' && $j(this).data('hover-border-color') !== false) { var hover_border_color = $j(this).data('hover-border-color'); var initial_border_color = $j(this).css('border-top-color'); $j(this).hover( function() { $j(this).css('border-color', hover_border_color); }, function() { $j(this).css('border-color', initial_border_color); }); } //hover color if(typeof $j(this).data('hover-color') !== 'undefined' && $j(this).data('hover-color') !== false) { var hover_color = $j(this).data('hover-color'); var initial_color = $j(this).css('color'); $j(this).hover( function() { $j(this).css('color', hover_color); }, function() { $j(this).css('color', initial_color); }); } }); } } function initSocialIconHover() { if($j('.q_social_icon_holder').length) { $j('.q_social_icon_holder').each(function() { //hover background color if(typeof $j(this).data('hover-background-color') !== 'undefined' && $j(this).data('hover-background-color') !== false) { var hover_background_color = $j(this).data('hover-background-color'); var initial_background_color = $j(this).find('.fa-stack').css('background-color'); $j(this).find('.fa-stack').hover( function() { $j(this).css('background-color', hover_background_color); }, function() { $j(this).css('background-color', initial_background_color); }); } //hover border color if(typeof $j(this).data('hover-border-color') !== 'undefined' && $j(this).data('hover-border-color') !== false) { var hover_border_color = $j(this).data('hover-border-color'); var initial_border_color = $j(this).find('.fa-stack').css('border-top-color'); $j(this).find('.fa-stack').hover( function() { $j(this).css('border-color', hover_border_color); }, function() { $j(this).css('border-color', initial_border_color); } ); } //hover color if(typeof $j(this).data('hover-color') !== 'undefined' && $j(this).data('hover-color') !== false) { var initial_color; var initial_style; var hover_color = $j(this).data('hover-color'); if($j(this).find('.fa-stack i, .fa-stack span').length) { initial_color = $j(this).find('.fa-stack i, .fa-stack span').css('color'); initial_style = $j(this).find('.fa-stack i, .fa-stack span').attr('style'); } else if($j(this).find('.simple_social').length) { initial_color = $j(this).find('.simple_social').css('color'); initial_style = $j(this).find('.simple_social').attr('style'); } if($j(this).find('.fa-stack').length) { $j(this).find('.fa-stack').hover( function() { $j(this).find('i, span').attr('style', function(i, s) { return initial_style + 'color: '+ hover_color + '!important;'}); }, function() { $j(this).find('i, span').attr('style', function(i, s) { return initial_style + 'color: ' + initial_color + '!important;' }); }); } else if($j(this).find('.simple_social').length) { $j(this).find('.simple_social').hover( function(){ $j(this).attr('style', function(i, s) { return initial_style + 'color: '+ hover_color + '!important;' }); }, function(){ $j(this).attr('style', function(i, s) { return initial_style + 'color: '+ initial_color + '!important;' }); }); } } }); } } function initTabsActiveBorder() { if($j('.q_tabs.vertical, .q_tabs.boxed').length) { $j('.q_tabs.vertical, .q_tabs.boxed').each(function(){ var parentBgColor = getParentBackgroundColor($j(this)); var activeElement = $j(this).find('li.active a'); if($j(this).hasClass('boxed')) { activeElement.css('border-bottom-color', parentBgColor); } if($j(this).hasClass('left')) { activeElement.css('border-right-color', parentBgColor); } if($j(this).hasClass('right')) { activeElement.css('border-left-color', parentBgColor); } }); } } function getParentBackgroundColor(element) { return element.parents().filter(function(){ var color = $j(this).css('background-color'); return color != 'transparent' && color != 'rgba(0, 0, 0, 0)'; }).eq(0).css('background-color') } function setActiveTabBorder() { if($j('.q_tabs li.active').length) { $j(this).click(function() { initTabsActiveBorder(); }); } } /* ** Popup menu initialization */ function initPopupMenu(){ "use strict"; if($j('a.popup_menu').length){ //var body_top; //set height of popup holder and initialize nicescroll $j(".popup_menu_holder_outer").height($window_height).niceScroll({ scrollspeed: 30, mousescrollstep: 20, cursorwidth: 0, cursorborder: 0, cursorborderradius: 0, cursorcolor: "transparent", autohidemode: false, horizrailenabled: false }); //200 is top and bottom padding of holder //set height of popup holder on resize $j(window).resize(function() {$j(".popup_menu_holder_outer").height($window_height)}); // Open popup menu $j('a.popup_menu').on('click',function(e){ e.preventDefault(); if(!$j(this).hasClass('opened')){ $j(this).addClass('opened'); $j('body').addClass('popup_menu_opened'); setTimeout(function(){ if(!$j('body').hasClass('page-template-full_screen-php')){ $j('body').css('overflow','hidden'); } },400); }else{ $j(this).removeClass('opened'); $j('body').removeClass('popup_menu_opened'); setTimeout(function(){ if(!$j('body').hasClass('page-template-full_screen-php')){ $j('body').css('overflow','visible'); } $j("nav.popup_menu ul.sub_menu").slideUp(200, function(){ $j('nav.popup_menu').getNiceScroll().resize(); }); },400); } }); //logic for open sub menus in popup menu $j(".popup_menu > ul > li.has_sub > a, .popup_menu > ul > li.has_sub > h6").on('tap click', function (e) { e.preventDefault(); if ($j(this).closest('li.has_sub').find("> ul.sub_menu").is(":visible")){ $j(this).closest('li.has_sub').find("> ul.sub_menu").slideUp(200, function(){ $j('.popup_menu_holder_outer').getNiceScroll().resize(); }); $j(this).closest('li.has_sub').removeClass('open_sub'); } else { $j(this).closest('li.has_sub').addClass('open_sub'); $j(this).closest('li.has_sub').find("> ul.sub_menu").slideDown(200, function(){ $j('.popup_menu_holder_outer').getNiceScroll().resize(); }); } return false; }); // $j(".popup_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > a > span.popup_arrow, .popup_menu > ul > li.has_sub > ul.sub_menu > li.has_sub > h6").click(function () { // if ($j(this).parent().parent().find("ul.sub_menu").is(":visible")){ // $j(this).parent().parent().find("ul.sub_menu").slideUp(200); // $j(this).parent().parent().removeClass('open_sub'); // } else { // $j(this).parent().parent().addClass('open_sub'); // $j(this).parent().parent().find("ul.sub_menu").slideDown(200); // } // }); //if link has no submenu and if it's not dead, than open that link $j(".popup_menu ul li:not(.has_sub) a").click(function () { if(($j(this).attr('href') !== "http://#") && ($j(this).attr('href') !== "#")){ $j('a.popup_menu').removeClass('opened'); $j('body').removeClass('popup_menu_opened').css('overflow','visible'); $j("nav.popup_menu ul.sub_menu").slideUp(200, function(){ $j('nav.popup_menu').getNiceScroll().resize(); }); }else{ return false; } }); } } function initFullScreenTemplate(){ "use strict"; if($j('.full_screen_holder').length && $window_width > 600){ // used for header style on changing sections, in checkFullScreenSectionsForHeaderStyle functions - START // var default_header_style = ''; if ($j('header.page_header').hasClass('light')) { default_header_style = 'light'; } else if ($j('header.page_header').hasClass('dark')) { default_header_style = 'dark'; } else { default_header_style = header_style_admin; } // used for header style on changing sections, in checkFullScreenSectionsForHeaderStyle functions - END // $j('.full_screen_preloader').css('height', ($window_height)); $j('#up_fs_button').on('click', function() { $j.fn.fullpage.moveSectionUp(); return false; }); $j('#down_fs_button').on('click', function() { $j.fn.fullpage.moveSectionDown(); return false; }); var section_number = $j('.full_screen_inner > .full_screen_section').length; $j('.full_screen_inner').fullpage({ sectionSelector: '.full_screen_section', scrollOverflow: true, afterLoad: function(anchorLink, index){ checkActiveArrowsOnFullScrrenTemplate(section_number, index); checkFullScreenSectionsForHeaderStyle(index, default_header_style); }, afterRender: function(){ checkActiveArrowsOnFullScrrenTemplate(section_number, 1); checkFullScreenSectionsForHeaderStyle(1, default_header_style); if(section_number !== 1){ $j('.full_screen_holder').find('.full_screen_navigation_holder').css('visibility','visible'); } $j('.full_screen_holder').find('.full_screen_inner').css('visibility','visible'); $j('.full_screen_preloader').hide(); if($j('.full_screen_holder video.full_screen_sections_video').length){ $j('.full_screen_holder video.full_screen_sections_video').each(function(){ $j(this).get(0).play(); }); } } }); } } function checkActiveArrowsOnFullScrrenTemplate(section_number, index){ "use strict"; if(index === 1){ $j('.full_screen_navigation_holder #up_fs_button').hide(); if(index != section_number){ $j('.full_screen_navigation_holder #down_fs_button').show(); } }else if(index === section_number){ if(section_number === 2){ $j('.full_screen_navigation_holder #up_fs_button').show(); } $j('.full_screen_navigation_holder #down_fs_button').hide(); }else{ $j('.full_screen_navigation_holder #up_fs_button').show(); $j('.full_screen_navigation_holder #down_fs_button').show(); } } function checkFullScreenSectionsForHeaderStyle(index, default_header_style){ "use strict"; if($j('[data-q_header_style]').length > 0 && $j('header').hasClass('header_style_on_scroll')) { if ($j($j('.full_screen_holder .full_screen_inner .full_screen_section')[index-1]).data("q_header_style") !== undefined) { var header_style = $j($j('.full_screen_holder .full_screen_inner .full_screen_section')[index-1]).data("q_header_style"); $j('header').removeClass('dark light').addClass(header_style); } else { $j('header').removeClass('dark light').addClass(default_header_style); } } } /* * Check header style on scroll */ function checkHeaderStyleOnScroll(){ "use strict"; if($j('[data-q_header_style]').length > 0 && $j('header').hasClass('header_style_on_scroll')){ //var offset = $j('header.page_header').height(); var default_header_style = ''; if($j('header.page_header').hasClass('light')){ default_header_style = 'light'; }else if($j('header.page_header').hasClass('dark')){ default_header_style = 'dark'; }else{ default_header_style = header_style_admin; } var paspartu_top_add = $j('body').hasClass('paspartu_on_top_fixed') ? Math.round($window_width*paspartu_width) : 0; var paspartu_bottom_add = $j('body').hasClass('paspartu_on_bottom_fixed') ? Math.round($window_width*paspartu_width) : 0; $j('.full_width_inner > .wpb_row.section, .full_width_inner > .parallax_section_holder, .container_inner > .wpb_row.section, .container_inner > .parallax_section_holder, .portfolio_single > .wpb_row.section').waypoint( function(direction) { if(direction === 'down') { if ($j(this).data("q_header_style") !== undefined) { var header_style = $j(this).data("q_header_style"); $j('header').removeClass('dark light').addClass(header_style); } else { $j('header').removeClass('dark light').addClass(default_header_style); } } }, { offset: 0 + paspartu_top_add}); //'title' class is added in selector because default header style is not set when there is title on the page and page is scrolled back to the top $j('.title, .full_width_inner > .wpb_row.section, .full_width_inner > .parallax_section_holder, .container_inner > .wpb_row.section, .container_inner > .parallax_section_holder, .portfolio_single > .wpb_row.section, .q_slider').waypoint( function(direction) { if(direction === 'up') { if ($j(this).data("q_header_style") !== undefined) { var header_style = $j(this).data("q_header_style"); $j('header').removeClass('dark light').addClass(header_style); } else { $j('header').removeClass('dark light').addClass(default_header_style); } } }, { offset: function(){ return -$j(this).outerHeight() + paspartu_bottom_add; } }); } } /* ** Image Gallery Slider with no space initialization */ function initImageGallerySliderNoSpace(){ if($j('.qode_image_gallery_no_space').length){ $j('.qode_image_gallery_no_space').each(function(){ $j(this).animate({'opacity': 1},1000); $j(this).find('.qode_image_gallery_holder').lemmonSlider({infinite: true}); }); //disable click on non active image $j('.qode_image_gallery_no_space').on('click', 'li:not(.active) a', function() { return false; }); } } /* ** Vertical Split Slider */ function initVerticalSplitSlider(){ "use strict"; if($j('html').hasClass('vertical_split_screen_initalized')){ $j('html').removeClass('vertical_split_screen_initalized'); $j.fn.multiscroll.destroy(); } if($j('.vertical_split_slider').length) { $j('.vertical_split_slider').height($window_height).animate({opacity:1},300); $j('.vertical_split_slider').multiscroll({ scrollingSpeed: 500, navigation: true, afterRender: function(){ $j('html').addClass('vertical_split_screen_initalized'); initButtonHover(); // this function need to be initialized after initVerticalSplitSlider if($j('div.wpcf7 > form').length){$j('div.wpcf7 > form').wpcf7InitForm();} // this function need to be initialized after initVerticalSplitSlider in order to initialize initCountdown(); if ($j('body').hasClass('vss_responsive_adv')){ //prepare html for smaller screens - start // var vertical_split_slider_responsive = $j("
      "); $j(".vertical_split_slider").after(vertical_split_slider_responsive); var left_side = $j('.vertical_split_slider .ms-left > div'); var right_side = $j('.vertical_split_slider .ms-right > div'); for(var i = 0; i < left_side.length; i++){ vertical_split_slider_responsive.append($j(left_side[i]).clone(true)); vertical_split_slider_responsive.append($j(right_side[left_side.length-1-i]).clone(true)); } } } }); if ($j('body').hasClass('vss_responsive_adv')){ if($window_width < 768){ $j.fn.multiscroll.destroy(); $j('html,body').css('height', 'auto').css('overflow', 'auto'); }else{ $j.fn.multiscroll.build(); $j('html,body').css('height', '100%').css('overflow', 'hidden'); } $j(window).resize(function() { if($window_width < 768){ $j.fn.multiscroll.destroy(); $j('html,body').css('height', 'auto').css('overflow', 'auto'); }else{ $j.fn.multiscroll.build(); $j('html,body').css('height', '100%').css('overflow', 'hidden'); } }); } }else{ if(!$j('.full_screen_holder').length) { //because this is not necessary on pages if there are full screen sections $j('html,body').css('height', 'auto').css('overflow', 'auto'); } } } /* ** Show Google Map */ function showGoogleMap(){ "use strict"; if($j('.qode_google_map').length){ $j('.qode_google_map').each(function(){ var custom_map_style; if(typeof $j(this).data('custom-map-style') !== 'undefined') { custom_map_style = $j(this).data('custom-map-style'); } var color_overlay; if(typeof $j(this).data('color-overlay') !== 'undefined' && $j(this).data('color-overlay') !== false) { color_overlay = $j(this).data('color-overlay'); } var saturation; if(typeof $j(this).data('saturation') !== 'undefined' && $j(this).data('saturation') !== false) { saturation = $j(this).data('saturation'); } var lightness; if(typeof $j(this).data('lightness') !== 'undefined' && $j(this).data('lightness') !== false) { lightness = $j(this).data('lightness'); } var zoom; if(typeof $j(this).data('zoom') !== 'undefined' && $j(this).data('zoom') !== false) { zoom = $j(this).data('zoom'); } var pin; if(typeof $j(this).data('pin') !== 'undefined' && $j(this).data('pin') !== false) { pin = $j(this).data('pin'); } var map_height; if(typeof $j(this).data('map-height') !== 'undefined' && $j(this).data('map-height') !== false) { map_height = $j(this).data('map-height'); } var unique_id; if(typeof $j(this).data('unique-id') !== 'undefined' && $j(this).data('unique-id') !== false) { unique_id = $j(this).data('unique-id'); } var google_maps_scroll_wheel; if(typeof $j(this).data('google-maps-scroll-wheel') !== 'undefined') { google_maps_scroll_wheel = $j(this).data('google-maps-scroll-wheel'); } var addresses; if(typeof $j(this).data('addresses') !== 'undefined' && $j(this).data('addresses') !== false) { addresses = $j(this).data('addresses'); } var map = "map_"+ unique_id; var geocoder = "geocoder_"+ unique_id; var holderId = "map_canvas_"+ unique_id; initializeGoogleMap(custom_map_style, color_overlay, saturation, lightness, google_maps_scroll_wheel, zoom, holderId, map_height, pin, map, geocoder, addresses) }); } } /* ** Init Google Map */ function initializeGoogleMap(custom_map_style, color, saturation, lightness, wheel, zoom, holderId, height, pin, map, geocoder, data){ "use strict"; var mapStyles = [ { stylers: [ {hue: color }, {saturation: saturation}, {lightness: lightness}, {gamma: 1} ] } ]; var google_map_type_id; if(custom_map_style){ google_map_type_id = 'qode_style' } else { google_map_type_id = google.maps.MapTypeId.ROADMAP } var qodeMapType = new google.maps.StyledMapType(mapStyles, {name: "Qode Google Map"}); geocoder = new google.maps.Geocoder(); var latlng = new google.maps.LatLng(-34.397, 150.644); var myOptions = { zoom: zoom, scrollwheel: wheel, center: latlng, zoomControl: true, zoomControlOptions: { style: google.maps.ZoomControlStyle.SMALL, position: google.maps.ControlPosition.RIGHT_CENTER }, scaleControl: false, scaleControlOptions: { position: google.maps.ControlPosition.LEFT_CENTER }, streetViewControl: false, streetViewControlOptions: { position: google.maps.ControlPosition.LEFT_CENTER }, panControl: false, panControlOptions: { position: google.maps.ControlPosition.LEFT_CENTER }, mapTypeControl: false, mapTypeControlOptions: { mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'qode_style'], style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, position: google.maps.ControlPosition.LEFT_CENTER }, mapTypeId: google_map_type_id }; map = new google.maps.Map(document.getElementById(holderId), myOptions); map.mapTypes.set('qode_style', qodeMapType); var index; for (index = 0; index < data.length; ++index) { initializeGoogleAddress(data[index], pin, map, geocoder); } var holder_element = document.getElementById(holderId); holder_element.style.height = height + "px"; } /* ** Init Google Map Addresses */ function initializeGoogleAddress(data, pin, map, geocoder){ "use strict"; if (data === '') return; var contentString = '
      '+ '
      '+ '
      '+ '
      '+ '

      '+data+'

      '+ '
      '+ '
      '; var infowindow = new google.maps.InfoWindow({ content: contentString }); geocoder.geocode( { 'address': data}, function(results, status) { if (status === google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location, icon: pin, title: data['store_title'] }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); google.maps.event.addDomListener(window, 'resize', function() { map.setCenter(results[0].geometry.location); }); } }); }; function checkSVG(element) { "use strict"; var el = element.find('.active .qode_slide-svg-holder'); var drawing_enabled = el.data('svg-drawing'); if (drawing_enabled === 'yes') { drawSVG(el); } } /** * Function for drawing slider svgs. Based on Codrops article 'SVG Drawing Animation' */ function drawSVG(svg){ "use strict"; var svgs = Array.prototype.slice.call( svg.find('svg') ), svgArr = [], resizeTimeout; // the svgs already shown... svgs.forEach( function( el, i ) { var svg = new SVGEl( el ); svgArr[i] = svg; setTimeout(function( el ) { return function() { svg.render(); }; }( el ), 0 );//0ms pause before drawing } ); } var docElem = window.document.documentElement; window.requestAnimFrame = function(){ return ( window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback){ window.setTimeout(callback, 1000 / 60); } ); }(); window.cancelAnimFrame = function(){ return ( window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame || function(id){ window.clearTimeout(id); } ); }(); function SVGEl( el ) { this.el = el; var frameRate = $j(this.el).closest('.qode_slide-svg-holder').data('svg-frames'); this.image = this.el.previousElementSibling; this.current_frame = 0; this.total_frames = frameRate;//number of frames defines speed of drawing this.path = []; this.length = []; this.handle = 0; this.init(); } SVGEl.prototype.init = function() { var self = this; [].slice.call( this.el.querySelectorAll( 'path' ) ).forEach( function( path, i ) { self.path[i] = path; var l = self.path[i].getTotalLength(); self.length[i] = l; self.path[i].style.strokeDasharray = l + ' ' + l; self.path[i].style.strokeDashoffset = l; } ); }; SVGEl.prototype.render = function() { if( this.rendered ) return; this.rendered = true; this.draw(); }; SVGEl.prototype.draw = function() { var self = this, progress = this.current_frame/this.total_frames; if (progress > 1) { window.cancelAnimFrame(this.handle); } else { this.current_frame++; for(var j=0, len = this.path.length; j 0) { var skrollr_title = skrollr.init({ edgeStrategy: 'set', smoothScrolling: false, forceHeight: false }); skrollr_title.refresh(); } }; function initQodeElementAnimationSkrollr() { "use strict"; if($j('.no-touch .carousel').length === 0) { var elementItemAnimation = $j('.no-touch .q_elements_holder > .q_elements_item'); elementItemAnimation.each(function(){ if((typeof($j(this).data('animation')) !== 'undefined' || typeof($j('.title_outer').data('animation')) !== 'undefined') && $j(this).data('animation') === 'yes') { var skr = skrollr.init(); skr.refresh(); return false; } }); } }; function initIconShortcodeHover() { "use strict"; if($j('.qode_icon_shortcode').length) { $j('.qode_icon_shortcode').each(function() { //check if icon type is circle of square if(typeof $j(this).data('type') !== 'undefined' && ['circle', 'square'].indexOf($j(this).data('type')) != -1) { if(typeof $j(this).data('hover-bg-color') !== 'undefined') { if($j(this).data('type') == 'circle') { var elementToHover = $j(this).find('i').first(); var hoverBgColor = $j(this).data('hover-bg-color'); var initialStyle = elementToHover.attr('style'); $j(this).hover(function() { elementToHover.attr('style', initialStyle + 'color: ' + hoverBgColor + '!important'); }, function() { elementToHover.attr('style', initialStyle); }); } else { var hoverBgColor = $j(this).data('hover-bg-color'); var initialBgColor = $j(this).css('background-color'); $j(this).hover(function() { $j(this).css('background-color', hoverBgColor); }, function() { $j(this).css('background-color', initialBgColor); }); } } } if(typeof $j(this).data('hover-icon-color') !== 'undefined') { var hoverColor = $j(this).data('hover-icon-color'); var initialColor = $j(this).find('.qode_icon_element ').css('color'); $j(this).hover(function() { $j(this).find('.qode_icon_element ').css('color', hoverColor); }, function() { $j(this).find('.qode_icon_element ').css('color', initialColor); }); } }); } } function initIconWithTextHover() { "use strict"; if($j('.qode_iwt_icon_holder').length) { $j('.qode_iwt_icon_holder').each(function() { if(typeof $j(this).data('icon-hover-bg-color') !== 'undefined') { var hoverBgColor = $j(this).data('icon-hover-bg-color'); var initialBgColor = $j(this).css('background-color'); $j(this).hover(function() { $j(this).css('background-color', hoverBgColor); }, function() { $j(this).css('background-color', initialBgColor); }); } if(typeof $j(this).data('icon-hover-color') !== 'undefined') { var elementToChange = $j(this).find('.qode_iwt_icon_element'); var hoverColor = $j(this).data('icon-hover-color'); var initialColor = elementToChange.css('color'); $j(this).hover(function() { elementToChange.css('color', hoverColor); }, function() { elementToChange.css('color', initialColor); }); } }); } } function initLoadNextPostOnBottom(){ "use strict"; if($j('.blog_vertical_loop').length) { var header_addition; var normal_header_addition; var paspartu_add = $j('body').hasClass('paspartu_enabled') ? Math.round($window_width*paspartu_width) : 0; if($j('header.page_header').hasClass('transparent')) { normal_header_addition = 0; }else{ normal_header_addition = header_height; } var click = true; var $container = $j('.blog_vertical_loop .blog_holder'); $j(document).on('click','.blog_vertical_loop_button a',function(e){ e.preventDefault(); if(click){ click = false; var $this = $j(this); var link = $this.attr('href'); var $content = '.blog_vertical_loop .blog_holder'; var $anchor = '.blog_vertical_loop_button_holder a'; var $next_href = $j($anchor).attr('href'); //check for mobile header if($window_width < 1000){ header_addition = $j('header.page_header').height(); }else{ header_addition = normal_header_addition; } var scrollTop = $j(window).scrollTop(), elementOffset = $this.closest('article').offset().top, distance = (elementOffset - scrollTop) - header_addition - paspartu_add; $container.find('article:eq(1)').addClass('fade_out'); $this.closest('article').addClass('move_up').removeClass('next_post').css('transform', 'translateY(-' + distance + 'px)'); setTimeout(function () { $j(window).scrollTop(0); $container.find('article:eq(0)').remove(); $container.find('article:eq(0)').addClass('previous_post'); $this.closest('article').removeAttr('style').removeClass('move_up'); }, 450); $j.get(link + '', function (data) { var $new_content = $j(data).find('article').addClass('next_post'); $next_href = $j($anchor, data).attr('href'); $container.append($j($new_content)); click = true; }); } else{ return false; } }); $j(document).on('click','.blog_vertical_loop_back_button a',function(e){ e.preventDefault(); if(click){ click = false; var $this = $j(this); var link = $this.attr('href'); var $content = '.blog_vertical_loop .blog_holder'; var $anchor = '.blog_vertical_loop_button_holder.prev_post a'; var $prev_href = $j($anchor).attr('href'); $container.find('article:eq(0)').removeClass('fade_out').addClass('fade_in'); $this.closest('article').addClass('move_up').css('transform', 'translateY(' + $window_height + 'px)'); setTimeout(function () { $container.find('article:last-child').remove(); $container.find('article:eq(0)').removeClass('previous_post fade_in'); $this.closest('article').addClass('next_post').removeAttr('style').removeClass('move_up'); $j.get(link + '', function (data) { var $new_content = $j(data).find('article').removeClass('next_post').addClass('previous_post'); //by default, posts have next_post class $prev_href = $j($anchor, data).attr('href'); $container.prepend($j($new_content)); click = true; }); }, 450); }else{ return false; } }); //load previous post on page load $j.get($j('.blog_vertical_loop_button_holder .last_page a').attr('href') + '', function (data) { var $new_content = $j(data).find('article').removeClass('next_post').addClass('previous_post'); //by default, posts have next_post class $container.prepend($j($new_content)); }); //load next post on page load $j.get($j('.blog_vertical_loop_button a').attr('href') + '', function (data) { var $new_content = $j(data).find('article').addClass('next_post'); $container.append($j($new_content)); }); } } /* Parallax Layers plugin */ (function ( $ ) { "use strict"; $.fn.extend({ mouseParallax: function(options) { var defaults = { moveFactor: 1.5, targetContainer: this }; var options = $.extend(defaults, options); return this.each(function() { var o = options; var layer_elements = $(o.targetContainer).find('.image, .paralax_layers_content_holder'); layer_elements.each(function(i){ $(this).css('z-index',i); }); var mouseXStart; var mouseYStart; mouseXStart = $(o.targetContainer).offset().left; mouseYStart = $(o.targetContainer).offset().top; $(o.targetContainer).on('mouseenter',function(e){ mouseXStart = e.pageX - $(this).offset().left; mouseYStart = e.pageY - $(this).offset().top; }); $(o.targetContainer).on('mousemove', function(e){ var mouseX0 = $(this).offset().left + mouseXStart; var mouseY0 = $(this).offset().top + mouseYStart; var mouseX = e.pageX - mouseX0; var mouseY = e.pageY - mouseY0; layer_elements.each(function(i){ $(this).css({ marginLeft : -mouseX / 100 * o.moveFactor*(i+1), marginTop : -mouseY / 100 * o.moveFactor*(i+1) },100); }); }); var config = { interval: 0, over: function(){}, timeout: 500, out: function(){ layer_elements.each(function(i){ $(this).stop().animate({ marginLeft: 0, marginTop: 0 },300); }); } }; $(o.targetContainer).hoverIntent(config); }); } }); } (jQuery) ); /** * Initialize parallax layers function */ function setParallaxLayersHeight($this, $def_height){ "use strict"; var parallax_layers_height = $def_height; var responsive_breakpoint_set = [1600,1300,1000,768,567,320]; if($window_width > responsive_breakpoint_set[0]){ parallax_layers_height = $def_height; }else if($window_width > responsive_breakpoint_set[1]){ parallax_layers_height = $def_height * 0.75; }else if($window_width > responsive_breakpoint_set[2]){ parallax_layers_height = $def_height * 0.6; }else if($window_width > responsive_breakpoint_set[3]){ parallax_layers_height = $def_height * 0.55; }else if($window_width <= responsive_breakpoint_set[3]){ parallax_layers_height = $def_height * 0.45; } $this.css({'height': (parallax_layers_height) + 'px'}); } function parallaxLayers(){ "use strict"; if($j('.qode_parallax_layers').length){ $j(".qode_parallax_layers").each(function(){ var $this = $j(this); if($j(this).hasClass('full_screen_height')){ $this.height($window_height); $j(window).resize(function () { $this.height($window_height); }); }else{ var $def_height = $j(this).data('height'); setParallaxLayersHeight($this, $def_height); $j(window).resize(function () { setParallaxLayersHeight($this, $def_height); }); } var $parallax_layers_holder = $this.find('.qode_parallax_layers_holder'); var counter = 0; var limit = $this.find(".image").length; $this.find(".image").each(function() { var $this = $j(this); if($this.css("background-image") != "" && $this.css("background-image") != "none") { var bg_url = $this.attr('style'); bg_url = bg_url.match(/url\(["']?([^'")]+)['"]?\)/); bg_url = bg_url ? bg_url[1] : ""; if (bg_url) { var backImg = new Image(); backImg.src = bg_url; $j(backImg).load(function(){ counter++; if(counter == limit){ $parallax_layers_holder.removeClass('preload_parallax_layers'); if($j('html').hasClass('no-touch')){$parallax_layers_holder.mouseParallax()}; } }); } } }); }); } } function alterWPMLSwitcherHeaderBottom() { "use strict"; if($j('.header_bottom .main_menu li.menu-item-language').length) { var langDropdown = $j('.header_bottom .main_menu .menu-item-language').find('.submenu-languages'); if(typeof langDropdown !== 'undefined') { langDropdown.parent('li').addClass('narrow'); langDropdown.wrap('
      '); langDropdown.show(); } } if($j('.header_bottom .mobile_menu li.menu-item-language').length) { var langDropdown = $j('.header_bottom .mobile_menu .menu-item-language').find('.submenu-languages'); if(typeof langDropdown !== 'undefined') { langDropdown.parent('li').addClass('has_sub'); langDropdown.prev('a').after(''); langDropdown.addClass('sub_menu'); } } } ================================================ FILE: core/docs/sources-asciidoc/src/main/asciidoc/stylesheets/telestax.css~ ================================================ @import url(https://fonts.googleapis.com/css?family=Varela+Round|Open+Sans:400italic,600italic,400,600|Ubuntu+Mono:400); /*! normalize.css v2.1.2 | MIT License | git.io/normalize */ /* ========================================================================== HTML5 display definitions ========================================================================== */ /** Correct `block` display not defined in IE 8/9. */ article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; } /** Correct `inline-block` display not defined in IE 8/9. */ audio, canvas, video { display: inline-block; } /** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */ audio:not([controls]) { display: none; height: 0; } /** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */ [hidden], template { display: none; } script { display: none !important; } /* ========================================================================== Base ========================================================================== */ /** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */ /** Remove default margin. */ body { margin: 0; } /* ========================================================================== Links ========================================================================== */ /** Remove the gray background color from active links in IE 10. */ a { background: transparent; } /** Address `outline` inconsistency between Chrome and other browsers. */ a:focus { outline: thin dotted; } /** Improve readability when focused and also mouse hovered in all browsers. */ a:active, a:hover { outline: 0; } /* ========================================================================== Typography ========================================================================== */ /** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */ h1 { font-size: 2em; margin: 0.67em 0; } /** Address styling not present in IE 8/9, Safari 5, and Chrome. */ abbr[title] { border-bottom: 1px dotted; } /** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */ b, strong { font-weight: bold; } /** Address styling not present in Safari 5 and Chrome. */ dfn { font-style: italic; } /** Address differences between Firefox and other browsers. */ hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; } /** Address styling not present in IE 8/9. */ mark { background: #ff0; color: #000; } /** Correct font family set oddly in Safari 5 and Chrome. */ code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; } /** Improve readability of pre-formatted text in all browsers. */ pre { white-space: pre-wrap; } /** Set consistent quote types. */ q { quotes: "\201C" "\201D" "\2018" "\2019"; } /** Address inconsistent and variable font size in all browsers. */ small { font-size: 80%; } /** Prevent `sub` and `sup` affecting `line-height` in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sup { top: -0.5em; } sub { bottom: -0.25em; } /* ========================================================================== Embedded content ========================================================================== */ /** Remove border when inside `a` element in IE 8/9. */ img { border: 0; } /** Correct overflow displayed oddly in IE 9. */ svg:not(:root) { overflow: hidden; } /* ========================================================================== Figures ========================================================================== */ /** Address margin not present in IE 8/9 and Safari 5. */ figure { margin: 0; } /* ========================================================================== Forms ========================================================================== */ /** Define consistent border, margin, and padding. */ fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; } /** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */ legend { border: 0; /* 1 */ padding: 0; /* 2 */ } /** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */ button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ } /** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */ button, input { line-height: normal; } /** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */ button, select { text-transform: none; } /** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */ button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ } /** Re-set default cursor for disabled elements. */ button[disabled], html input[disabled] { cursor: default; } /** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */ input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ } /** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */ input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; } /** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */ input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } /** Remove inner padding and border in Firefox 4+. */ button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; } /** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */ textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ } /* ========================================================================== Tables ========================================================================== */ /** Remove most spacing between table cells. */ table { border-collapse: collapse; border-spacing: 0; } meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; } meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; } meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; } *, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } html, body { font-size: 100%; } body { background: #fefdfd; color: rgba(0, 0, 0, 0.8); padding: 0; margin: 0; font-family: "Open Sans", sans-serif; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; } a:hover { cursor: pointer; } img, object, embed { height: 100%; width: 100%; max-width: 100%; height: auto; } object, embed { height: 100%; } img { -ms-interpolation-mode: bicubic; } #map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; } .left { float: left !important; } .right { float: right !important; } .text-left { text-align: left !important; } .text-right { text-align: right !important; } .text-center { text-align: center !important; } .text-justify { text-align: justify !important; } .hide { display: none; } .antialiased, body { -webkit-font-smoothing: antialiased; } img { display: inline-block; vertical-align: middle; } textarea { height: auto; min-height: 50px; } select { width: 100%; } object, svg { display: inline-block; vertical-align: middle; } .center { margin-left: auto; margin-right: auto; } .spread { width: 100%; } p.lead, .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { font-size: 1.21875em; line-height: 1.6; } .subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.25; color: #002c5e; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; } /* Typography resets */ div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; } /* Default Link Styles */ a { color: #005580; text-decoration: underline; line-height: inherit; } a:hover, a:focus { color: #078d71; } a img { border: none; } /* Default paragraph styles */ p { font-family: inherit; font-weight: normal; font-size: 1em; line-height: 1.5; margin-bottom: 1.25em; text-rendering: optimizeLegibility; } p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; } /* Default header styles */ h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: "Varela Round", sans-serif; font-weight: 400; font-style: normal; color: #00326b; text-rendering: optimizeLegibility; margin-top: 0.8em; margin-bottom: 0.5em; line-height: 1.0625em; } h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small {color: #057aff; line-height: 0; } h1 { font-size: 2.125em; } h2 { font-size: 1.6875em; } h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; } h4 { font-size: 1.125em; } h5 { font-size: 1.125em; } h6 { font-size: 1em; } hr { border: solid rgba(145, 135, 84, 0.15); border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; } /* Helpful Typography Defaults */ em, i { font-style: italic; line-height: inherit; } strong, b { font-weight: bold; line-height: inherit; } small { font-size: 60%; line-height: inherit; } code { font-family: "Ubuntu Mono", "Inconsolata", monospace; font-weight: 400; color: #331d00; } /* Lists */ ul, ol, dl { font-size: 1em; line-height: 1.5; margin-bottom: 1.25em; list-style-position: outside; font-family: inherit; } ul, ol { margin-left: 1.5em; } ul.no-bullet, ol.no-bullet { margin-left: 1.5em; } /* Unordered Lists */ ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ } ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; } ul.square { list-style-type: square; } ul.circle { list-style-type: circle; } ul.disc { list-style-type: disc; } ul.no-bullet { list-style: none; } /* Ordered Lists */ ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; } /* Definition Lists */ dl dt { margin-bottom: 0.3125em; font-weight: bold; } dl dd { margin-bottom: 1.25em; } /* Abbreviations */ abbr, acronym { text-transform: uppercase; font-size: 90%; color: rgba(0, 0, 0, 0.8); border-bottom: 1px dotted #dddddd; cursor: help; } abbr { text-transform: none; } /* Blockquotes */ blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; } blockquote cite { display: block; font-size: 0.8125em; color: #666666; } blockquote cite:before { content: "\2014 \0020"; } blockquote cite a, blockquote cite a:visited { color: #666666; } blockquote, blockquote p { line-height: 1.5; color: #999999; } /* Microformats */ .vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #dddddd; padding: 0.625em 0.75em; } .vcard li { margin: 0; display: block; } .vcard .fn { font-weight: bold; font-size: 0.9375em; } .vevent .summary { font-weight: bold; } .vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; } @media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.25; } h1 { font-size: 2.75em; } h2 { font-size: 2.3125em; } h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; } h4 { font-size: 1.4375em; } } /* Tables */ table { background: white; margin-bottom: 1.25em; border: solid 1px rgba(145, 135, 84, 0.15); } table thead, table tfoot { background: rgba(119, 84, 22, 0.1); font-weight: bold; } table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: rgba(0, 0, 0, 0.8); text-align: left; } table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: rgba(0, 0, 0, 0.8); } table tr.even, table tr.alt, table tr:nth-of-type(even) { background: rgba(119, 84, 22, 0.025); } table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.5; } body { tab-size: 4; } h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.25; } .clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; } .clearfix:after, .float-group:after { clear: both; } *:not(pre) > code { font-size: 0.86667em; font-style: normal !important; letter-spacing: 0; padding: 1px 5px 1px 5px; background-color: transparent; border: 1px solid #dddddd; -webkit-border-radius: 3px; border-radius: 3px; line-height: inherit; } pre, pre > code { line-height: 1.6; color: white; font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: normal; } .keyseq { color: rgba(51, 51, 51, 0.8); } kbd { font-family: "Ubuntu Mono", "Inconsolata", monospace; display: inline-block; color: rgba(0, 0, 0, 0.8); font-size: 0.65em; line-height: 1.45; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: 0 0.15em; padding: 0.2em 0.5em; vertical-align: middle; position: relative; top: -0.1em; white-space: nowrap; } .keyseq kbd:first-child { margin-left: 0; } .keyseq kbd:last-child { margin-right: 0; } .menuseq, .menu { color: rgba(0, 0, 0, 0.8); } b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; } b.button:before { content: "["; padding: 0 3px 0 2px; } b.button:after { content: "]"; padding: 0 2px 0 3px; } p a > code:hover { color: #1a0f00; } #header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; } #header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; } #header:after, #content:after, #footnotes:after, #footer:after { clear: both; } #content { margin-top: 1.25em; } #content:before { content: none; } #header > h1:first-child { color: #703f1c; margin-top: 2.25rem; margin-bottom: 0; } #header > h1:first-child + #toc { margin-top: 8px; border-top: 1px solid rgba(145, 135, 84, 0.15); } #header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { border-bottom: 1px solid rgba(145, 135, 84, 0.15); padding-bottom: 8px; } #header .details { border-bottom: 1px solid rgba(145, 135, 84, 0.15); line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: #666666; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; } #header .details span:first-child { margin-left: -0.125em; } #header .details span.email a { color: #999999; } #header .details br { display: none; } #header .details br + span:before { content: "\00a0\2013\00a0"; } #header .details br + span.author:before { content: "\00a0\22c5\00a0"; color: #999999; } #header .details br + span#revremark:before { content: "\00a0|\00a0"; } #header #revnumber { text-transform: capitalize; } #header #revnumber:after { content: "\00a0"; } #content > h1:first-child:not([class]) { color: #703f1c; border-bottom: 1px solid rgba(145, 135, 84, 0.15); padding-bottom: 8px; margin-top: 0; padding-top: 1rem; margin-bottom: 1.25rem; } #toc { border-bottom: 0px solid #dddddd; padding-bottom: 0.5em; } #toc > ul { margin-left: 0.125em; } #toc ul.sectlevel0 > li > a { font-style: italic; } #toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; } #toc ul { font-family: "Varela Round", sans-serif; list-style-type: none; } #toc li { line-height: 1.3334; margin-top: 0.3334em; } #toc a { text-decoration: none; } #toc a:active { text-decoration: underline; } #toctitle { color: #002c5e; font-size: 1.2em; } @media only screen and (min-width: 768px) { #toctitle { font-size: 1.375em; } body.toc2 { padding-left: 15em; padding-right: 0; } #toc.toc2 { margin-top: 0 !important; background-color: #f2f2f4; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #dddddd; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; } #toc.toc2 #toctitle { margin-top: 0; margin-bottom: 0.8rem; font-size: 1.2em; } #toc.toc2 > ul { font-size: 0.9em; margin-bottom: 0; } #toc.toc2 ul ul { margin-left: 0; padding-left: 1em; } #toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; } body.toc2.toc-right { padding-left: 0; padding-right: 15em; } body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #dddddd; left: auto; right: 0; } } @media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; } #toc.toc2 { width: 20em; } #toc.toc2 #toctitle { font-size: 1.375em; } #toc.toc2 > ul { font-size: 0.95em; } #toc.toc2 ul ul { padding-left: 1.25em; } body.toc2.toc-right { padding-left: 0; padding-right: 20em; } } #content #toc { border-style: solid; border-width: 1px; border-color: #d6d6dd; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f4; -webkit-border-radius: 6px; border-radius: 6px; } #content #toc > :first-child { margin-top: 0; } #content #toc > :last-child { margin-bottom: 0; } #footer { max-width: 100%; background-color: #0b445a; padding: 1.25em; } #footer-text { color: #fefdfd; line-height: 1.35; } .sect1 { padding-bottom: 0.625em; } @media only screen and (min-width: 768px) { .sect1 { padding-bottom: 1.25em; } } .sect1 + .sect1 { border-top: 0px solid #dddddd; } #content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { position: absolute; z-index: 1001; width: 1.5ex; margin-left: -1.5ex; display: block; text-decoration: none !important; visibility: hidden; text-align: center; font-weight: normal; } #content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: "\00A7"; display: block; padding-top: 0.1em; } #content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; } #content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: #00326b; text-decoration: none; } #content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: #002652; } .audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; } .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; } table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; } .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { color: #703f1c; } table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; } content > img { width:100%; height:100%; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover; } .admonitionblock > table { border-collapse: separate; border: 0; background: none; width: 100%; } .admonitionblock > table td.icon { vertical-align: middle; text-align: center; width: 80px; } .admonitionblock > table td.icon img { max-width: none; } .admonitionblock > table td.icon .title { font-weight: bold; font-family: "Varela Round", sans-serif; text-transform: uppercase; } .admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid rgba(145, 135, 84, 0.15); color: #666666; text-align: left;} .admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; } .exampleblock > .content { border-style: solid; border-width: 1px; border-color: #eddbdb; margin-bottom: 1.25em; padding: 1.25em; background: #fefdfd; -webkit-border-radius: 6px; border-radius: 6px; } .exampleblock > .content > :first-child { margin-top: 0; } .exampleblock > .content > :last-child { margin-bottom: 0; } .sidebarblock { border-style: solid; border-width: 1px; border-color: #d6d6dd; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f4; -webkit-border-radius: 6px; border-radius: 6px; } .sidebarblock > :first-child { margin-top: 0; } .sidebarblock > :last-child { margin-bottom: 0; } .sidebarblock > .content > .title { color: #002c5e; margin-top: 0; } .exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; } .literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { background: rgba(16, 195, 196, 0.05); } .sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { background: #f2f1f1; } .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 1px solid rgba(16, 195, 196, 0.125); -webkit-border-radius: 6px; border-radius: 6px; word-wrap: break-word; padding: 1em; font-size: 0.8125em; } .literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; } @media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.90625em; } } @media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 1em; } } .literalblock.output pre { color: rgba(16, 195, 196, 0.05); background-color: inherit; } .literalblock > .content pre, .listingblock > .content pre { background: #333333; border-width: 2px; border-style: solid; border-color: #dddddd; -webkit-border-radius: 3px; border-radius: 3px; padding: 0.66667em; word-wrap: break-word; } .listingblock pre.highlightjs { padding: 0; } .listingblock pre.highlightjs > code { padding: 1em; -webkit-border-radius: 6px; border-radius: 6px; } /*.listingblock > .content { position: relative; }*/ .listingblock > .content pre, .listingblock > .content pre { background: #333333; border-width: 2px; border-style: solid; border-color: #dddddd; -webkit-border-radius: 3px; border-radius: 3px; padding: 0.66667em; word-wrap: break-word; } .listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: #999; } .listingblock:hover code[data-lang]:before { display: block; } .listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; } .listingblock.terminal pre .command:not([data-prompt]):before { content: "$"; } table.pyhltable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; } table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; line-height: 1.4; } table.pyhltable td.code { padding-left: .75em; padding-right: 0; } pre.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid rgba(145, 135, 84, 0.15); } pre.pygments .lineno { display: inline-block; margin-right: .25em; } table.pyhltable .linenodiv { background: none !important; padding-right: 0 !important; } .quoteblock { margin: 0 1em 1.25em 1.5em; display: table; } .quoteblock > .title { margin-left: -1.5em; margin-bottom: 0.75em; } .quoteblock blockquote, .quoteblock blockquote p { color: #999999; font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; } .quoteblock blockquote { margin: 0; padding: 0; border: 0; } .quoteblock blockquote:before { content: "\201c"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: #002c5e; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } .quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; } .quoteblock .attribution { margin-top: 0.5em; margin-right: 0.5ex; text-align: right; } .quoteblock .quoteblock { margin-left: 0; margin-right: 0; padding: 0.5em 0; border-left: 3px solid #666666; } .quoteblock .quoteblock blockquote { padding: 0 0 0 0.75em; } .quoteblock .quoteblock blockquote:before { display: none; } .verseblock { margin: 0 1em 1.25em 1em; } .verseblock pre { font-family: "Open Sans", "DejaVu Sans", sans; font-size: 1.15rem; color: #999999; font-weight: 300; text-rendering: optimizeLegibility; } .verseblock pre strong { font-weight: 400; } .verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; } .quoteblock .attribution, .verseblock .attribution { font-size: 0.8125em; line-height: 1.45; font-style: italic; } .quoteblock .attribution br, .verseblock .attribution br { display: none; } .quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.025em; color: #666666; } .quoteblock.abstract { margin: 0 0 1.25em 0; display: block; } .quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { text-align: left; word-spacing: 0; } .quoteblock.abstract blockquote:before, .quoteblock.abstract blockquote p:first-of-type:before { display: none; } table.tableblock { max-width: 100%; border-collapse: separate; } table.tableblock td > .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; } table.tableblock, th.tableblock, td.tableblock { border: 0 solid rgba(145, 135, 84, 0.15); } table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; } table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; } table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; } table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; } table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; } table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0; } table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; } table.frame-all { border-width: 1px; } table.frame-sides { border-width: 0 1px; } table.frame-topbot { border-width: 1px 0; } th.halign-left, td.halign-left { text-align: left; } th.halign-right, td.halign-right { text-align: right; } th.halign-center, td.halign-center { text-align: center; } th.valign-top, td.valign-top { vertical-align: top; } th.valign-bottom, td.valign-bottom { vertical-align: bottom; } th.valign-middle, td.valign-middle { vertical-align: middle; } table thead th, table tfoot th { font-weight: bold; } tbody tr th { display: table-cell; line-height: 1.5; background: rgba(119, 84, 22, 0.1); } tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: rgba(0, 0, 0, 0.8); font-weight: bold; } p.tableblock > code:only-child { background: none; padding: 0; } p.tableblock { font-size: 1em; } td > div.verse { white-space: pre; } ol { margin-left: 1.75em; } ul li ol { margin-left: 1.5em; } dl dd { margin-left: 1.125em; } dl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; } ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.625em; } ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; } ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; } ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { width: 1em; font-size: 0.85em; } ul.checklist li > p:first-child > input[type="checkbox"]:first-child { width: 1em; position: relative; top: 1px; } ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; } ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; } ul.inline > li > * { display: block; } .unstyled dl dt { font-weight: normal; font-style: normal; } ol.arabic { list-style-type: decimal; } ol.decimal { list-style-type: decimal-leading-zero; } ol.loweralpha { list-style-type: lower-alpha; } ol.upperalpha { list-style-type: upper-alpha; } ol.lowerroman { list-style-type: lower-roman; } ol.upperroman { list-style-type: upper-roman; } ol.lowergreek { list-style-type: lower-greek; } .hdlist > table, .colist > table { border: 0; background: none; } .hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; } td.hdlist1, td.hdlist2 { vertical-align: top; padding: 0 0.625em; } td.hdlist1 { font-weight: bold; padding-bottom: 1.25em; } .literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; } .colist > table tr > td:first-of-type { padding: 0 0.75em; line-height: 1; } .colist > table tr > td:last-of-type { padding: 0.25em 0; } .thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; } .imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; } .imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; } .imageblock > .title { margin-bottom: 0; } .imageblock.thumb, .imageblock.th { border-width: 6px; } .imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; } .image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; } .image.left { margin-right: 0.625em; } .image.right { margin-left: 0.625em; } a.image { text-decoration: none; display: inline-block; } a.image object { pointer-events: none; } sup.footnote, sup.footnoteref { font-size: 0.875em; position: static; vertical-align: super; } sup.footnote a, sup.footnoteref a { text-decoration: none; } sup.footnote a:active, sup.footnoteref a:active { text-decoration: underline; } #footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; } #footnotes hr { width: 20%; min-width: 6.25em; margin: -0.25em 0 0.75em 0; border-width: 1px 0 0 0; } #footnotes .footnote { padding: 0 0.375em 0 0.225em; line-height: 1.3334; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.05em; margin-bottom: 0.2em; } #footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; } #footnotes .footnote:last-of-type { margin-bottom: 0; } #content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; } .gist .file-data > table { border: 0; background: #fff; width: 100%; margin-bottom: 0; } .gist .file-data > table td.line-data { width: 99%; } div.unbreakable { page-break-inside: avoid; } .big { font-size: larger; } .small { font-size: smaller; } .underline { text-decoration: underline; } .overline { text-decoration: overline; } .line-through { text-decoration: line-through; } .aqua { color: #00bfbf; } .aqua-background { background-color: #00fafa; } .black { color: black; } .black-background { background-color: black; } .blue { color: #0000bf; } .blue-background { background-color: #0000fa; } .fuchsia { color: #bf00bf; } .fuchsia-background { background-color: #fa00fa; } .gray { color: #606060; } .gray-background { background-color: #7d7d7d; } .green { color: #006000; } .green-background { background-color: #007d00; } .lime { color: #00bf00; } .lime-background { background-color: #00fa00; } .maroon { color: #600000; } .maroon-background { background-color: #7d0000; } .navy { color: #000060; } .navy-background { background-color: #00007d; } .olive { color: #606000; } .olive-background { background-color: #7d7d00; } .purple { color: #600060; } .purple-background { background-color: #7d007d; } .red { color: #bf0000; } .red-background { background-color: #fa0000; } .silver { color: #909090; } .silver-background { background-color: #bcbcbc; } .teal { color: #006060; } .teal-background { background-color: #007d7d; } .white { color: #bfbfbf; } .white-background { background-color: #fafafa; } .yellow { color: #bfbf00; } .yellow-background { background-color: #fafa00; } span.icon > .fa { cursor: default; } .admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); cursor: default; } .admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #004060; } .admonitionblock td.icon .icon-tip:before { content: "\f0eb"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; } .admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #bf6900; } .admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #bf3400; } .admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #bf0000; } .conum[data-value] { display: inline-block; color: #fff !important; background-color: rgba(0, 0, 0, 0.8); -webkit-border-radius: 100px; border-radius: 100px; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family: "Open Sans", "DejaVu Sans", sans-serif; font-style: normal; font-weight: bold; } .conum[data-value] * { color: #fff !important; } .conum[data-value] + b { display: none; } .conum[data-value]:after { content: attr(data-value); } pre .conum[data-value] { position: relative; top: -0.125em; } b.conum * { color: inherit !important; } .conum:not([data-value]):empty { display: none; } #toc.toc2 ul ul { list-style-type: circle; padding-left: 2em; } .sect1 { padding-bottom: 0 !important; margin-bottom: 2.5em; } #header h1 { font-weight: bold; position: relative; left: -0.0625em; } #content h2, #content h3, #content #toctitle, #content .sidebarblock > .content > .title, #content h4, #content h5, #content #toctitle { position: relative; left: -0.0625em; } #content h2 { font-weight: bold; } .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { color: black; } pre.pygments.highlight { background-color: rgba(16, 195, 196, 0.05); } .pygments .tok-err { border: none !important; color: #800000 !important; } .pygments .tok-c { color: #999 !important; } /*Telestax stylesheet.css */ .wp-caption, .wp-caption-text, .sticky, .gallery-caption, .bypostauthor{ opacity: 1; } .clearfix:before, .clearfix:after { content: " "; /* 1 */ display: table; /* 2 */ } .clearfix:after { clear: both; } .clearfix { *zoom: 1; } .clear:after { clear: both; content: ""; display: block; } /* Webkit */ ::selection { background: #f25f33; color: #fff; } /* Gecko/Mozilla */ ::-moz-selection { background: #f25f33 color: #fff; } .alignleft { float: left; margin: 0 20px 20px 0; } .alignright { float: right; margin: 0 0 20px 20px; } .aligncenter { display: block; margin: 10px auto; } .header_top .aligncenter{ margin: 8px auto; } .text-align-right { text-align: right; } .text-align-left { text-align: left; } .text-align-center { text-align: center; } /*.content ul ul, .content ol ol{ padding:0 0 0 15px; }*/ /* =Reset default browser CSS. -------------------------------------------------------------- */ html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font, ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td { background: transparent; border: 0; margin: 0; padding: 0; vertical-align: baseline; outline: none; } article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; } blockquote { quotes: none; } blockquote:before,blockquote:after { content: ''; content: none; } del { text-decoration: line-through; } /* tables still need 'cellspacing="0"' in the markup */ table { border-collapse: collapse; border-spacing: 0; border: medium none; vertical-align: middle; } table th{ border: 0; padding: 5px 7px; text-align: center; } table td { padding: 5px 10px; text-align: center; } a img { border: none; } img{ max-width: 100%; height: auto; } h1,h2,h3,h4,h5,h6{ color: #303030; } h1{ font-size: 30px; line-height: 1.25em; /* 20px/16px */ } h2{ font-size: 24px; line-height: 1.384615384615385em; /* 36px/26px */ text-transform:uppercase; letter-spacing:1px; font-weight: 600; } h3{ font-size: 17px; line-height: 1.304347826086957em; /* 30px/23px */ text-transform:uppercase; letter-spacing:1px; font-weight: 600; } h4{ font-size: 19px; line-height: 1.375em; /* 22px/16px */ font-weight: 400; } h5{ font-size: 15px; line-height: 1.571428571428571em; /* 22px/14px */ text-transform:uppercase; letter-spacing:1px; font-weight: 600; } h6{ font-size: 13px; line-height: 1.538461538461538em; /* 20px/13px */ text-transform:uppercase; letter-spacing:1px; font-weight:600; } h1 a, h2 a, h3 a, h4 a, h5 a, h6 a{ color: #303030; } h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover{ color: #1abc9c; } a, p a{ color: #303030; text-decoration: none; cursor: pointer; } a:hover, p a:hover { color: #1abc9c; text-decoration: none; } input[type='submit'], .woocommerce input[type='button'], .woocommerce-page input[type='button']{ -webkit-appearance: none; } ul{ list-style-position:inside; } /* =Structure -------------------------------------------------------------- */ html{ height: 100%; margin: 0px !important; -webkit-transition: all 1.3s ease-out; -moz-transition: all 1.3s ease-out; -o-transition: all 1.3s ease-out; -ms-transition: all 1.3s ease-out; transition: all 1.3s ease-out; } body{ font-family: 'Roboto', sans-serif; font-size: 16px; line-height: 26px; color: #818181; font-weight: 400; background-color: #f6f6f6; overflow-y: scroll; overflow-x: hidden !important; -webkit-font-smoothing: antialiased; } .wrapper { background-color: #f6f6f6; position: relative; z-index: 1000; -webkit-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -moz-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -o-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -ms-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); left: 0px; } .right_side_menu_opened .wrapper{ left: -270px; } .right_side_menu_opened .wrapper header.fixed, .right_side_menu_opened .wrapper header.fixed_hiding, .right_side_menu_opened .wrapper header.sticky, .right_side_menu_opened .wrapper header.fixed_top_header .top_header{ left: -270px; } @media only screen and (min-width: 1100px){ .right_side_menu_opened:not(.boxed) .carousel-inner:not(.relative_position){ left: -270px !important; } } .wrapper_inner{ width: 100%; overflow: hidden; } body.boxed .wrapper_inner{ overflow: visible; } body.boxed .content{ overflow: hidden; } .meta{ display: none; } .ajax_loader { position: fixed; top: 50%; left: 50%; z-index: 1100; display: none; } @media only screen and (min-width: 1000px){ body.vertical_menu_enabled:not(.vertical_menu_hidden) .ajax_loader{ margin-left: 130px; } body.vertical_menu_enabled.vertical_menu_hidden .ajax_loader{ margin-left: 20px; } } .ajax_loader_1 { position: relative; display: inline-block; width: 100%; height: 100%; } .ajax_loader_2 { margin: -50% 0 0 -50%; } /* pulse - start */ .ajax_loader .pulse { width: 32px; height: 32px; margin: -16px 0px 0px -16px; background-color: #303030; -webkit-border-radius: 16px; -moz-border-radius: 16px; -ms-border-radius: 16px; -o-border-radius: 16px; border-radius: 16px; -webkit-animation: scaleout 1.0s infinite ease-in-out; animation: scaleout 1.0s infinite ease-in-out; } @-webkit-keyframes scaleout { 0% { -webkit-transform: scale(0); } 100% { -webkit-transform: scale(1); opacity: 0; } } @-moz-keyframes scaleout { 0% { -moz-transform: scale(0); } 100% { -moz-transform: scale(1); opacity: 0; } } @-ms-keyframes scaleout { 0% { -ms-transform: scale(0); } 100% { -ms-transform: scale(1); opacity: 0; } } @-o-keyframes scaleout { 0% { -o-transform: scale(0); } 100% { -o-transform: scale(1); opacity: 0; } } @keyframes scaleout { 0% { transform: scale(0); -webkit-transform: scale(0); } 100% { transform: scale(1); -webkit-transform: scale(1); opacity: 0; } } /* pulse - end */ /* double pulse - start */ .ajax_loader .double_pulse { width: 40px; height: 40px; margin: -20px 0px 0px -20px; position: relative; } .ajax_loader .double_pulse .double-bounce1, .ajax_loader .double_pulse .double-bounce2 { width: 100%; height: 100%; border-radius: 50%; background-color: #303030; opacity: 0.6; position: absolute; top: 0; left: 0; -webkit-animation: bounce 2.0s infinite ease-in-out; animation: bounce 2.0s infinite ease-in-out; } .ajax_loader .double_pulse .double-bounce2 { -webkit-animation-delay: -1.0s; animation-delay: -1.0s; } @-webkit-keyframes bounce { 0%, 100% { -webkit-transform: scale(0.0) } 50% { -webkit-transform: scale(1.0) } } @keyframes bounce { 0%, 100% { transform: scale(0.0); -webkit-transform: scale(0.0); } 50% { transform: scale(1.0); -webkit-transform: scale(1.0); } } /* double pulse - end */ /* cube - start */ .ajax_loader .cube { width: 60px; height: 60px; margin: -30px 0px 0px -30px; background-color: #303030; -webkit-animation: rotateplane 1.2s infinite ease-in-out; animation: rotateplane 1.2s infinite ease-in-out; } @-webkit-keyframes rotateplane { 0% { -webkit-transform: perspective(120px) } 50% { -webkit-transform: perspective(120px) rotateY(180deg) } 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) } } @keyframes rotateplane { 0% { transform: perspective(120px) rotateX(0deg) rotateY(0deg); -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg) } 50% { transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg) } 100% { transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } } /* cube - end */ /* rotating cubes - start */ .ajax_loader .rotating_cubes { width: 32px; height: 32px; margin: -16px 0px 0px -16px; position: relative; } .ajax_loader .rotating_cubes .cube1, .ajax_loader .rotating_cubes .cube2 { background-color: #303030; width: 10px; height: 10px; position: absolute; top: 0; left: 0; -webkit-animation: cubemove 1.8s infinite ease-in-out; animation: cubemove 1.8s infinite ease-in-out; } .ajax_loader .rotating_cubes .cube2 { -webkit-animation-delay: -0.9s; animation-delay: -0.9s; } @-webkit-keyframes cubemove { 25% { -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5) } 50% { -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg) } 75% { -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5) } 100% { -webkit-transform: rotate(-360deg) } } @keyframes cubemove { 25% { transform: translateX(42px) rotate(-90deg) scale(0.5); -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5); } 50% { transform: translateX(42px) translateY(42px) rotate(-179deg); -webkit-transform: translateX(42px) translateY(42px) rotate(-179deg); } 50.1% { transform: translateX(42px) translateY(42px) rotate(-180deg); -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg); } 75% { transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); } 100% { transform: rotate(-360deg); -webkit-transform: rotate(-360deg); } } /* rotating cubes - end */ /* stripes - start */ .ajax_loader .stripes { width: 50px; height: 60px; margin: -30px 0px 0px -25px; text-align: center; font-size: 10px; } .ajax_loader .stripes > div { background-color: #303030; height: 100%; width: 6px; display: inline-block; margin: 0 3px 0 0; -webkit-animation: stretchdelay 1.2s infinite ease-in-out; animation: stretchdelay 1.2s infinite ease-in-out; } .ajax_loader .stripes .rect2 { -webkit-animation-delay: -1.1s; animation-delay: -1.1s; } .ajax_loader .stripes .rect3 { -webkit-animation-delay: -1.0s; animation-delay: -1.0s; } .ajax_loader .stripes .rect4 { -webkit-animation-delay: -0.9s; animation-delay: -0.9s; } .ajax_loader .stripes .rect5 { -webkit-animation-delay: -0.8s; animation-delay: -0.8s; } @-webkit-keyframes stretchdelay { 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } 20% { -webkit-transform: scaleY(1.0) } } @keyframes stretchdelay { 0%, 40%, 100% { transform: scaleY(0.4); -webkit-transform: scaleY(0.4); } 20% { transform: scaleY(1.0); -webkit-transform: scaleY(1.0); } } /* stripes - end */ /* wave - start */ .ajax_loader .wave { width: 72px; text-align: center; margin: -9px 0px 0px -36px; } .ajax_loader .wave > div { width: 18px; height: 18px; background-color: #303030; margin: 0px 3px 0px 0px; border-radius: 100%; display: inline-block; -webkit-animation: bouncedelay 1.4s infinite ease-in-out; animation: bouncedelay 1.4s infinite ease-in-out; /* Prevent first frame from flickering when animation starts */ -webkit-animation-fill-mode: both; animation-fill-mode: both; } .ajax_loader .wave .bounce1 { -webkit-animation-delay: -0.32s; animation-delay: -0.32s; } .ajax_loader .wave .bounce2 { -webkit-animation-delay: -0.16s; animation-delay: -0.16s; } @-webkit-keyframes bouncedelay { 0%, 80%, 100% { -webkit-transform: scale(0.0) } 40% { -webkit-transform: scale(1.0) } } @keyframes bouncedelay { 0%, 80%, 100% { transform: scale(0.0); -webkit-transform: scale(0.0); } 40% { transform: scale(1.0); -webkit-transform: scale(1.0); } } /* wave - end */ /* two_rotating_circles - start */ .ajax_loader .two_rotating_circles { width: 40px; height: 40px; margin: -20px 0px 0px -20px; position: relative; text-align: center; -webkit-animation: rotatecircles 2.0s infinite linear; animation: rotatecircles 2.0s infinite linear; } .ajax_loader .two_rotating_circles .dot1, .ajax_loader .two_rotating_circles .dot2 { width: 60%; height: 60%; display: inline-block; position: absolute; top: 0; background-color: #303030; border-radius: 100%; -webkit-animation: bounce 2.0s infinite ease-in-out; animation: bounce 2.0s infinite ease-in-out; } .ajax_loader .two_rotating_circles .dot2 { top: auto; bottom: 0px; -webkit-animation-delay: -1.0s; animation-delay: -1.0s; } @-webkit-keyframes rotatecircles { 100% { -webkit-transform: rotate(360deg) }} @keyframes rotatecircles { 100% { transform: rotate(360deg); -webkit-transform: rotate(360deg) }} /* two_rotating_circles - end */ /* five_rotating_circles - start */ .ajax_loader .five_rotating_circles { width: 60px; height: 60px; margin: -30px 0px 0px -30px; position: relative; } .ajax_loader .five_rotating_circles .container1 > div, .ajax_loader .five_rotating_circles .container2 > div, .ajax_loader .five_rotating_circles .container3 > div { width: 12px; height: 12px; background-color: #303030; border-radius: 100%; position: absolute; -webkit-animation: bouncedelay 1.2s infinite ease-in-out; animation: bouncedelay 1.2s infinite ease-in-out; /* Prevent first frame from flickering when animation starts */ -webkit-animation-fill-mode: both; animation-fill-mode: both; } .ajax_loader .five_rotating_circles .spinner-container { position: absolute; width: 100%; height: 100%; } .ajax_loader .five_rotating_circles .container2 { -webkit-transform: rotateZ(45deg); transform: rotateZ(45deg); } .ajax_loader .five_rotating_circles .container3 { -webkit-transform: rotateZ(90deg); transform: rotateZ(90deg); } .ajax_loader .five_rotating_circles .circle1 { top: 0; left: 0; } .ajax_loader .five_rotating_circles .circle2 { top: 0; right: 0; } .ajax_loader .five_rotating_circles .circle3 { right: 0; bottom: 0; } .ajax_loader .five_rotating_circles .circle4 { left: 0; bottom: 0; } .ajax_loader .five_rotating_circles .container2 .circle1 { -webkit-animation-delay: -1.1s; animation-delay: -1.1s; } .ajax_loader .five_rotating_circles .container3 .circle1 { -webkit-animation-delay: -1.0s; animation-delay: -1.0s; } .ajax_loader .five_rotating_circles .container1 .circle2 { -webkit-animation-delay: -0.9s; animation-delay: -0.9s; } .ajax_loader .five_rotating_circles .container2 .circle2 { -webkit-animation-delay: -0.8s; animation-delay: -0.8s; } .ajax_loader .five_rotating_circles .container3 .circle2 { -webkit-animation-delay: -0.7s; animation-delay: -0.7s; } .ajax_loader .five_rotating_circles .container1 .circle3 { -webkit-animation-delay: -0.6s; animation-delay: -0.6s; } .ajax_loader .five_rotating_circles .container2 .circle3 { -webkit-animation-delay: -0.5s; animation-delay: -0.5s; } .ajax_loader .five_rotating_circles .container3 .circle3 { -webkit-animation-delay: -0.4s; animation-delay: -0.4s; } .ajax_loader .five_rotating_circles .container1 .circle4 { -webkit-animation-delay: -0.3s; animation-delay: -0.3s; } .ajax_loader .five_rotating_circles .container2 .circle4 { -webkit-animation-delay: -0.2s; animation-delay: -0.2s; } .ajax_loader .five_rotating_circles .container3 .circle4 { -webkit-animation-delay: -0.1s; animation-delay: -0.1s; } /* five_rotating_circles - end */ body.smooth_scroll { overflow-y: hidden; } body.boxed .wrapper_inner, body.boxed .footer_inner{ width: 1150px; margin: 0 auto; } /* ========================================================================== Header styles ========================================================================== */ /** * Generic header styles */ header { width: 100%; display: inline-block; margin: 0px 0px 0px 0px; vertical-align: middle; position: relative; z-index: 110; -webkit-backface-visibility:hidden; } header .header_inner_left { position: absolute; left: 45px; top: 0px; } header .container_inner .header_inner_left{ position: absolute; left: 0px; top: 0px; } .boxed header{ background-color: transparent !important; border: 0px !important; } .boxed .header_inner{ width: 1150px; margin: 0px auto; } .header_inner_right{ float: right; position: relative; z-index: 110; } /* Header top styles ========================================================================== */ .header_top { position: relative; z-index: 111; line-height: 33px; height: 33px; padding: 0; font-size: 15px; background-color: #fff; -webkit-transition: all 0.2s ease 0s; -moz-transition: all 0.2s ease 0s; -o-transition: all 0.2s ease 0s; transition: all 0.2s ease 0s; } header.scrolled .header_top { background-color: #fff !important; } .header_top p{ line-height: 32px; padding: 0 15px; } .header_top .left{ float: left; } .header_top .right{ float: right; } .header_top .right .inner #lang_sel { float: left; padding: 0 0 0 0px; } .header_top .inner #lang_sel > ul { list-style: none; } .header_top .left .inner > div, .header_top .left .inner > div:last-child { float:left; border-bottom: 0; border-top: 0; } .header_top .right .inner > div { border-left: 0; float: left; } header.scrolled:not(.scroll_header_top_area) .header_top { border-bottom: 0; } /* header widgets in light and dark header styles ========================================================================== */ header.light:not(.sticky) .q_social_icon_holder i.simple_social, header.light:not(.sticky) .header-widget, header.light:not(.sticky) .header-widget.widget_nav_menu ul.menu > li > a, header.light:not(.sticky) .header-widget p, header.light:not(.sticky) .header-widget a, header.light:not(.sticky) .header-widget span, header.light.header_style_on_scroll .q_social_icon_holder i.simple_social, header.light.header_style_on_scroll .header-widget, header.light.header_style_on_scroll .header-widget.widget_nav_menu ul.menu > li > a, header.light.header_style_on_scroll .header-widget p, header.light.header_style_on_scroll .header-widget a, header.light.header_style_on_scroll .header-widget span{ color:#ffffff; } header.light:not(.sticky) .q_social_icon_holder i.simple_social, header.light:not(.sticky) #lang_sel > ul > li > a, header.light:not(.sticky) #lang_sel_click > ul > li> a, header.light.header_style_on_scroll .q_social_icon_holder i.simple_social, header.light.header_style_on_scroll #lang_sel > ul > li > a, header.light.header_style_on_scroll #lang_sel_click > ul > li> a, header.light:not(.sticky) .textwidget span, header.light:not(.sticky) .textwidget span:hover, header.light.header_style_on_scroll .textwidget span, header.light.header_style_on_scroll .textwidget span:hover{ color:#fff !important; } header.dark:not(.sticky) .q_social_icon_holder i.simple_social, header.dark:not(.sticky) .header-widget, header.dark:not(.sticky) .header-widget.widget_nav_menu ul.menu > li > a, header.dark:not(.sticky) .header-widget p, header.dark:not(.sticky) .header-widget a, header.dark:not(.sticky) .header-widget span, header.dark.header_style_on_scroll .q_social_icon_holder i.simple_social, header.dark.header_style_on_scroll .header-widget, header.dark.header_style_on_scroll .header-widget.widget_nav_menu ul.menu > li > a, header.dark.header_style_on_scroll .header-widget p, header.dark.header_style_on_scroll .header-widget a, header.dark.header_style_on_scroll .header-widget span{ color:#000; } header.dark:not(.sticky) .q_social_icon_holder i.simple_social, header.dark:not(.sticky) #lang_sel > ul > li > a, header.dark:not(.sticky) #lang_sel_click > ul > li> a, header.dark.header_style_on_scroll .q_social_icon_holder i.simple_social, header.dark.header_style_on_scroll #lang_sel > ul > li > a, header.dark.header_style_on_scroll #lang_sel_click > ul > li> a, header.dark:not(.sticky) .textwidget span, header.dark:not(.sticky) .textwidget span:hover, header.dark.header_style_on_scroll .textwidget span, header.dark.header_style_on_scroll .textwidget span:hover{ color:#000 !important; } /* Header bottom styles ========================================================================== */ .header_bottom { padding: 0px 45px; position: relative; background-color: #fff; -webkit-transition: all 0.2s ease 0s; -moz-transition: all 0.2s ease 0s; -o-transition: all 0.2s ease 0s; transition: all 0.2s ease 0s; } .boxed .header_bottom{ padding: 0px 25px; } /* Generic logo styles ========================================================================== */ .logo_wrapper{ height: 100px; float: left; } .q_logo{ position: relative; top: 50%; left: 0px; } .q_logo a{ position: relative; display: block; visibility: hidden; } .q_logo img{ display: block; opacity:1; position: absolute; top: -50%; width: auto !important; max-width: none; -webkit-transition: opacity 0.6s ease-in-out; -moz-transition: opacity 0.6s ease-in-out; -o-transition: opacity 0.6s ease-in-out; -ms-transition: opacity 0.6s ease-in-out; } /* Specific logo styles */ .q_logo img.light, .q_logo img.sticky, .q_logo img.dark, .q_logo img.popup, .q_logo img.mobile { opacity:0; } header.scrolled:not(.header_style_on_scroll) .q_logo img.normal, header.scrolled.dark:not(.header_style_on_scroll) .q_logo img.normal, header.scrolled.light:not(.header_style_on_scroll) .q_logo img.normal { opacity: 1; } header.scrolled:not(.header_style_on_scroll) .q_logo img.light, header.scrolled.light:not(.header_style_on_scroll) .q_logo img.light, header.scrolled.dark:not(.header_style_on_scroll) .q_logo img.light, header.scrolled:not(.header_style_on_scroll) .q_logo img.dark, header.scrolled.light:not(.header_style_on_scroll) .q_logo img.dark, header.scrolled.dark:not(.header_style_on_scroll) .q_logo img.dark { opacity: 0; } header.light .q_logo img.normal{ opacity:0; } header.light .q_logo img.light{ opacity:1; } header.light .q_logo img.dark{ opacity:0; } header.dark .q_logo img.normal{ opacity:0; } header.dark .q_logo img.light{ opacity:0; } header.dark .q_logo img.dark{ opacity:1; } /* Sticky header styles ========================================================================== */ .hide_inital_sticky header.stick{ -ms-transform: translateY(-100%); -webkit-transform: translateY(-100%); transform: translateY(-100%); } .hide_inital_sticky header.stick.sticky{ -ms-transform: none; -webkit-transform: none; transform: none; } header.sticky { -webkit-transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -moz-transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -o-transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -ms-transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); transition: all 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); top: -120px; left: 0; position: fixed; -moz-background-clip:border; -webkit-background-clip:border; background-clip:border-box; -moz-background-clip:padding; -webkit-background-clip:padding; background-clip:padding-box; -moz-background-clip:content; -webkit-background-clip:content; background-clip:content-box; } header.sticky .header_top{ display: none; } header.sticky .header_bottom { background-color: #fff !important; box-shadow: 0 1px 3px rgba(0,0,0,0.11); } header.sticky.no_shadow .header_bottom { box-shadow: none; } header.sticky.centered_logo { top: -300px; } header.sticky.sticky_animate { top:0px; } header.sticky:not(.header_style_on_scroll) .q_logo img.sticky { opacity:1; } header.sticky:not(.header_style_on_scroll) .q_logo img.normal, header.sticky:not(.header_style_on_scroll) .q_logo img.light, header.sticky:not(.header_style_on_scroll) .q_logo img.dark, header.sticky:not(.header_style_on_scroll) .q_logo img.popup, header.sticky:not(.header_style_on_scroll) .q_logo img.mobile{ opacity:0 !important; } header.sticky .logo_wrapper, header.sticky.centered_logo .logo_wrapper{ height: 60px !important; float: left; } header.sticky .drop_down .second{ margin-top: 0; } header.sticky .header_fixed_right_area { display: none; } header.sticky .side_menu_button{ height: 60px; } .sticky .header_menu_bottom{ position: static; } /* Fixed header styles ========================================================================== */ header.fixed, header.fixed_hiding, header.fixed_top_header .top_header{ -webkit-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -moz-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -o-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -ms-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); width: 100%; position: fixed; z-index: 110; top:0px; left: 0px; } header.fixed.scrolled .header_bottom, header.fixed_hiding.scrolled .header_bottom{ -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.11); -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.11); box-shadow: 0 1px 3px rgba(0,0,0,0.11); background-color: #fff; } /* Header with menu on bottom styles ========================================================================== */ header.menu_bottom .header_inner_left { left: 0; } header:not(.sticky) .header_menu_bottom nav.main_menu > ul > li > a { line-height: 60px; } header:not(.sticky) .header_menu_bottom nav.main_menu > ul > li:first-child > a { padding-left: 0; } header.menu_bottom:not(.sticky) .drop_down .second { top: 100%; } header:not(.sticky) .header_menu_bottom .side_menu_button { height: 60px; } header.menu_bottom.has_header_fixed_right .mobile_menu_button { height: 130px; } header.menu_bottom .header_inner_left{ position: relative; } .menu_bottom.sticky .container_inner .header_inner_left{ position: absolute; } .menu_bottom .logo_wrapper{ float: none; } .menu_bottom .q_logo a{ display:inline-block; } .menu_bottom.sticky .logo_wrapper{ float: left; } .header_menu_bottom { position: relative; display: block; } /* Header styles when logo is in center ========================================================================== */ header.centered_logo{ text-align: center; } header.centered_logo .header_inner_left{ float: none; position: relative; display: block; margin: 20px 0px 10px 0px; } header.centered_logo.sticky .header_inner_left{ margin: 0px; } header.centered_logo .logo_wrapper{ float: none; height: auto !important; } header.centered_logo .q_logo{ top: 0px; } header.centered_logo.sticky .q_logo{ top: 50%; } header.centered_logo .q_logo a{ display: inline-block; vertical-align: middle; } header.centered_logo .q_logo img{ top: 0px; margin: 0px; } @media only screen and (min-width: 1000px){ header.centered_logo:not(.sticky ) .q_logo img{ /* only not sticky is set here because on sticky menu logo is moved left from site left edge */ -webkit-transform: translate(-50%, 0px); -moz-transform: translate(-50%, 0px); -ms-transform: translate(-50%, 0px); -o-transform: translate(-50%, 0px); transform: translate(-50%, 0px); } } header.centered_logo.centered_logo_animate .q_logo img, header:not(.centered_logo) .q_logo img{ height: 100%; } header.centered_logo.sticky .q_logo img{ top: -50%; } header.centered_logo.sticky .q_logo img{ height: 100% !important; } header.centered_logo .header_inner_right{ float: none; display: inline-block; position: relative; vertical-align: middle; } header.centered_logo .header_right_widget{ float: left; } header.centered_logo nav.main_menu, header.centered_logo nav.main_menu.right{ position: relative; display: inline-block; left: auto; float: none; vertical-align: middle; } header.centered_logo nav.main_menu > ul{ left: 0px; } @media only screen and (min-width: 1000px){ header.fixed_hiding .holeder_for_hidden_menu{ overflow: hidden; max-height: 150px; vertical-align: middle; -webkit-transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; -moz-transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; -o-transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; -ms-transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; transition: max-height 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s; } header.fixed_hiding.scrolled .holeder_for_hidden_menu{ max-height: 0px; } header.fixed_hiding .holeder_for_hidden_menu:hover{ overflow: visible; } header.fixed_hiding.scrolled:hover .holeder_for_hidden_menu{ max-height: 150px; transition-duration: 0.5s; -webkit-transition-duration: 0.8s; -moz-transition-duration: 0.8s; -ms-transition-duration: 0.8s; -o-transition-duration: 0.8s; } header.fixed_hiding.centered_logo .header_inner_left{ margin: 20px 0px; display: table; width: 100%; } header.fixed_hiding.centered_logo.fixed_hiding .header_inner_left{ height: 50px; } header.fixed_hiding .header-left-from-logo-widget, header.fixed_hiding .header-right-from-logo-widget, header.fixed_hiding .logo_wrapper{ display: table-cell; width: 33.33%; vertical-align: middle; position: relative; } header.fixed_hiding .header-left-from-logo-widget-inner, header.fixed_hiding .header-right-from-logo-widget-inner{ width: 100%; } header.fixed_hiding .header-left-from-logo-widget{ text-align: left; } header.fixed_hiding .header-right-from-logo-widget{ text-align: right; } header.fixed_hiding .q_logo a, header.fixed_hiding .q_logo{ max-height: 124px; opacity: 1; -webkit-transition: max-height 0.2s ease 0s, opacity 0.2s ease 0s; -moz-transition: max-height 0.2s ease 0s, opacity 0.2s ease 0s; -o-transition: max-height 0.2s ease 0s, opacity 0.2s ease 0s; -ms-transition: max-height 0.2s ease 0s, opacity 0.2s ease 0s; transition: max-height 0.2s ease-out 0s, opacity 0.2s ease 0s; } header.fixed_hiding.scrolled .q_logo, header.fixed_hiding.scrolled .q_logo a{ -webkit-transition: max-height 0.2s ease 0s, opacity 0.4s ease 0s; -moz-transition: max-height 0.2s ease 0s, opacity 0.4s ease 0s; -o-transition: max-height 0.2s ease 0s, opacity 0.4s ease 0s; -ms-transition: max-height 0.2s ease 0s, opacity 0.4s ease 0s; transition: max-height 0.2s ease-out 0s, opacity 0.4s ease 0s; max-height: 0px !important; opacity: 0; } header.fixed_hiding .q_logo_hidden a{ height: 50px; position: relative; display: block; opacity: 0; max-height: 0px; -webkit-transition: opacity 0s ease 0s, max-height 0s ease 0s; -moz-transition: opacity 0s ease 0s, max-height 0s ease 0s; -o-transition: opacity 0s ease 0s, max-height 0s ease 0s; -ms-transition: opacity 0s ease 0s, max-height 0s ease 0s; transition: opacity 0s ease 0s, max-height 0s ease 0s; } header.fixed_hiding.scrolled .q_logo_hidden a{ max-height: 500px; opacity: 1; -webkit-transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; -moz-transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; -o-transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; -ms-transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; transition: opacity 0.15s ease 0.3s, max-height 0.15s ease 0.2s; } } /* Main navigation styles ========================================================================== */ nav.main_menu{ position: absolute; left: 50%; z-index: 100; text-align: left; } nav.main_menu.right{ position: relative; left: auto; float: right; } nav.main_menu ul { list-style:none outside none; margin:0px; padding:0px; } nav.main_menu > ul { left: -50%; position: relative; } nav.main_menu.right > ul{ left: auto; } nav.main_menu ul li{ display:inline-block; float:left; padding:0px; margin:0px; background-repeat: no-repeat; background-position: right; } nav.main_menu ul li a { color: #777; font-weight: 400; text-decoration: none; display: inline-block; position: relative; line-height: 100px; padding: 0; margin: 0; cursor: pointer; } nav.main_menu > ul > li > a > i.menu_icon { margin-right: 7px; } header.sticky nav.main_menu > ul > li > a, .light.sticky nav.main_menu > ul > li > a, .light.sticky nav.main_menu > ul > li > a:hover, .light.sticky nav.main_menu > ul > li.active > a, .dark.sticky nav.main_menu > ul > li > a, .dark.sticky nav.main_menu > ul > li > a:hover, .dark.sticky nav.main_menu > ul > li.active > a{ line-height: 60px; } nav.main_menu > ul > li > a, nav.main_menu > ul > li > a { display: inline-block; height: 100%; background-color: transparent; -webkit-transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; -moz-transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; -o-transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; -ms-transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; transition: opacity 0.3s ease-in-out, color 0.3s ease-in-out; } .with_hover_bg_color nav.main_menu > ul > li > a { -webkit-transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; -moz-transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; -ms-transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; -o-transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; transition: background-color 0 ease-in-out 0.15s, color 0 ease-in-out 0.15s; } header:not(.with_hover_bg_color) nav.main_menu > ul > li:hover > a{ opacity: 0.8; } nav.main_menu>ul>li.active > a { color: #303030; } nav.main_menu > ul > li > a > i.blank{ display: none; } nav.main_menu > ul > li.has_sub > a > i.q_menu_arrow { display: inline-block; margin-left: 6px; } .light:not(.sticky):not(.scrolled) nav.main_menu > ul > li > a, .light:not(.sticky):not(.scrolled) nav.main_menu > ul > li > a:hover, .light:not(.sticky):not(.scrolled) nav.main_menu > ul > li.active > a, .light:not(.sticky):not(.scrolled) nav.main_menu > ul > li:before, .light:not(.sticky):not(.scrolled) nav.main_menu > ul > li > a, .light.header_style_on_scroll nav.main_menu > ul > li > a:hover, .light.header_style_on_scroll nav.main_menu > ul > li.active > a, .light.header_style_on_scroll nav.main_menu > ul > li:before{ color: #fff; } .dark:not(.sticky):not(.scrolled) nav.main_menu > ul > li > a, .dark:not(.sticky):not(.scrolled) nav.main_menu > ul > li.active > a, .dark:not(.sticky):not(.scrolled) nav.main_menu > ul > li:not(:first-child):before, .dark.header_style_on_scroll nav.main_menu > ul > li > a, .dark.header_style_on_scroll nav.main_menu > ul > li.active > a, .dark.header_style_on_scroll nav.main_menu > ul > li:not(:first-child):before{ color: #000; } nav.main_menu > ul > li > a { position: relative; padding: 0 17px; color: #9d9d9d; text-transform: uppercase; font-weight: 600; font-size: 13px; letter-spacing: 1px; } /* DROP DOWN MENU - START */ .drop_down ul{ list-style: none; } .drop_down ul li{ position: relative; } header.transparent.fixed.scrolled .drop_down .second, header.transparent.fixed_hiding.scrolled .drop_down .second{ top: 100%; } .drop_down .second { left: 0; margin: 0; top: 100%; position: absolute; display: block; visibility: hidden; overflow: hidden; opacity: 0; z-index: 10; /*margin-top: 1px;*/ -webkit-transition: top 0.3s ease-in-out; -moz-transition: top 0.3s ease-in-out; -ms-transition: top 0.3s ease-in-out; -o-transition: top 0.3s ease-in-out; transition: top 0.3s ease-in-out; } header.transparent:not(.sticky) .drop_down .second { top: 75%; } header.transparent.with_border:not(.sticky) .drop_down .second, header.transparent.with_hover_bg_color:not(.sticky) .drop_down .second { top: 100%; } .drop_down li.left_position .second{ left: auto; right: 0px; } header.transparent .drop_down .second:not(.right) { left: 16px; } header.transparent.with_hover_bg_color .drop_down .second:not(.right) { left: 0; } .drop_down li.right_position .second { left: -100%; /*right: 0;*/ } .drop_down .second.drop_down_start{ visibility: visible; overflow: visible; opacity: 1; } nav.main_menu > ul > li:hover > .second{ z-index: 20; } .drop_down .second .inner{ position: relative; padding: 0px; display: block; z-index: 997; } .drop_down .second .inner > ul, li.narrow .second .inner ul { display:inline-block; position: relative; background-color: #262626; border-color:#3d3d3d; } li.narrow .second .inner ul { padding: 7px 0; } .drop_down .second .inner ul li { display: block; padding: 0 15px; position: relative; float: none; height: auto; background: 0; width: 190px; } li.narrow .second .inner ul li:last-child { border-bottom: none; } .drop_down .wide.left_position .second ul li, .drop_down .wide.right_position .second ul li { width: 180px; } .drop_down .second .inner ul li a, .drop_down .second .inner ul li h5 { display: block; font-weight: 600; color: #9d9d9d; height: auto; line-height: 16px; margin: 0; padding: 9px 0; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; } .drop_down .second .inner > ul > li:last-child > a, .drop_down .second .inner > ul > li > ul > li:last-child > a, .drop_down .second .inner > ul > li > ul > li > ul > li:last-child > a { border-bottom: 0; } .drop_down .second .inner ul.right li a{ padding: 9px 20px 9px 0; } .drop_down .second .inner > ul > li > a:hover, .drop_down .second .inner ul li.sub ul li a:hover{ color: #fff; /*background-color: #474747;*/ } .drop_down .narrow .second .inner ul li { padding: 0; width: 225px; } .drop_down .narrow .second .inner ul li a { padding-left: 20px; padding-right: 20px; } .drop_down .wide .second ul li a, .drop_down .wide .second .inner ul li.sub a, .drop_down .wide .second .inner ul li h5 { background: 0; } .drop_down .second i { display: none; } .drop_down .second .inner ul li ul{ position: absolute; left: 100%; top: -7px; height: auto; display: none; overflow: hidden; z-index: 10; } .drop_down .second .inner ul li:hover ul{ z-index: 20; display: block; } .drop_down .second.right { right: 0px; left: auto; } .drop_down .second .inner ul.right li a, .drop_down .second .inner ul.right li h5{ text-align: right; } .drop_down .second .inner ul.right li ul{ left: -100%; } .drop_down .second .inner ul li.sub ul li a, .drop_down .second .inner ul.right li.sub ul li a{ background: none; } .drop_down .second .inner .widget{ padding: 0px 20px; } .drop_down .second .inner .widget p{ font-size: 13px; line-height: 16px; padding: 12px 0px; } /* DROP DOWN MENU - END */ /* DROP DOWN MENU WIDE - START */ .drop_down .wide .second ul{ padding: 15px 10px; } .drop_down .second ul li{ border-bottom-width: 1px; border-bottom-color: #3d3d3d; } .drop_down .wide .second ul li{ float: left; width: 249px; padding: 0 10px 0 10px; border-left: 1px solid #3d3d3d; border-bottom: 0; } .drop_down .wide .second > .inner > ul > li.sub > ul > li > a, .drop_down .wide .second ul li a { padding: 11px 9px; } .drop_down .wide:not(.right_position) .second ul li:first-child, .drop_down .wide.right_position .second ul li:last-child { border-left-color: transparent; } .drop_down .wide .second ul li:last-child { margin-right: 0; } .drop_down .wide.right_position .second ul li{ float: right; } .drop_down .wide .second ul li:hover{ background-color: transparent; } .drop_down .wide .second ul li:nth-child(4n+1){ clear: both; } .drop_down .second .inner ul li.sub a i.q_menu_arrow{ display: inline-block; float: right; position: relative; top: 2px; font-size: 12px; color: #888; } .drop_down .second .inner ul li.sub ul li a i.q_menu_arrow, .drop_down .wide .second .inner ul li.sub a i.q_menu_arrow { display: none; } .drop_down .second .inner ul.right li.sub a i.q_menu_arrow{ float: left; -ms-transform: rotate(180deg); -moz-transform: rotate(180deg); -webkit-transform: rotate(180deg); } .drop_down .wide .second .inner > ul > li > a{ color: #fff; border-bottom: 0; text-transform: uppercase; letter-spacing: 1px; font-weight: 600; } .drop_down .wide .second .inner > ul > li > a{ margin-bottom: 7px; font-size: 13px; } .drop_down .wide .second .inner ul li.sub h5 a, .drop_down .wide .second .inner ul li h5 a{ padding: 0px !important; } .drop_down .wide .second ul li ul{ display: block; left: 0; padding: 0; position: relative; top: 0; visibility: visible; background-color: transparent !important; } .drop_down .wide .second ul li ul .widget{ padding:0 10px; } /* Wide drop down with full width background styles ========================================================================== */ .drop_down .wide.wide_background .second{ background-color: #262626; } .drop_down .wide.wide_background .second .inner{ text-align:center; } .drop_down .wide.wide_background .second .inner ul{ text-align:left; } .drop_down .wide.wide_background .second .inner { text-align: center; } /* custom widget area in popup - start */ .drop_down .second .inner ul li ul{ overflow: visible; } .drop_down .wide .second ul li.show_widget_area_in_popup:hover .popup_wrapper > a{ color: #fff; /* this is added to style dynamic css also! */ } .drop_down .wide .second ul li.show_widget_area_in_popup .popup_wrapper{ position: relative; display: inline-block; vertical-align: middle; } .drop_down .wide .second ul li.show_widget_area_in_popup a{ display: inline-block; vertical-align: middle; } .drop_down .wide .second ul li.show_widget_area_in_popup .widget{ height: 0px; width: 0px; overflow: hidden; opacity: 0; position: absolute; left: 100%; top: 0px; padding: 5px; margin: 5px 0px 0px 5px; background-color: #262626; } .drop_down .wide .second ul li ul li{ z-index: 1; } .drop_down .wide .second ul li.show_widget_area_in_popup:hover{ z-index: 10; } .drop_down .wide .second ul li.show_widget_area_in_popup:hover .widget{ height: auto; width: auto; opacity: 1; } .drop_down .wide .second ul li.show_widget_area_in_popup .widget img{ max-width: inherit; display: block; position: relative; } .drop_down .wide .second ul li.show_widget_area_in_popup .widget a{ padding: 0px; } /* custom widget area in popup - end */ .drop_down .wide .second ul li ul li{ padding: 0; margin: 0; border: 0; } .drop_down .wide .second ul li ul li.menu-item-has-children > a, .drop_down .wide .second ul li ul li.menu-item-has-children > a:hover{ border-bottom: 0 none; color: #303030; font-size: 15px; } /* DROP DOWN MENU WIDE - END */ /* DROP DOWN MENU WIDE ICONS - START */ .drop_down .wide.icons .second ul li a span{ position: relative; display: block; } .drop_down .wide.icons .second i{ width: 24px; height: 16px; float: left; display: inline-block; color: #888; line-height: 16px; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; } .drop_down .wide.icons .second a:hover i{ color: #fff; } .drop_down .wide.icons .second i.blank{ background: none; border: 0px; display:none; } /* DROP DOWN MENU WIDE ICONS - END */ /* Sticky with left and right menu - start */ @media only screen and (min-width: 1000px){ header.stick_with_left_right_menu:not(.sticky){ text-align: center; } .hide_inital_sticky header.stick_with_left_right_menu{ -ms-transform: translateY(-100%); -webkit-transform: translateY(-100%); transform: translateY(-100%); } .hide_inital_sticky header.stick_with_left_right_menu.sticky{ -ms-transform: none; -webkit-transform: none; transform: none; } header.stick_with_left_right_menu .header_inner_left{ display: inline-block; vertical-align: middle; position: relative; top: 0px; left: auto; z-index: 100; } header.stick_with_left_right_menu.sticky .header_inner_left{ display: none; } header.stick_with_left_right_menu nav.main_menu.left_side{ text-align: right; position: absolute; width: 49%; top: 0px; left: 0px; z-index: 50; } header.stick_with_left_right_menu nav.main_menu.left_side > ul{ text-align: left; display: inline-block; vertical-align: middle; } header.stick_with_left_right_menu nav.main_menu.right_side{ position: absolute; width: 49%; top: 0px; right: 0px; left: auto; z-index: 50; } header.stick_with_left_right_menu nav.main_menu.left_side:hover, header.stick_with_left_right_menu nav.main_menu.right_side:hover{ z-index: 200; } header.stick_with_left_right_menu.sticky nav.main_menu.left_side, header.stick_with_left_right_menu.sticky nav.main_menu.right_side{ position: relative; display: inline-block; vertical-align: middle; } header.stick_with_left_right_menu.sticky nav.main_menu.left_side > ul > li:last-child, header.stick_with_left_right_menu.sticky nav.main_menu.right_side > ul > li:first-child{ margin: 0px !important; } nav.main_menu.left_side > ul, nav.main_menu.right_side > ul{ left: auto; } } /* Sticky with left and right menu - end */ /* Fixed Minimal header type styles ========================================================================== */ .fixed_minimal .container_inner .header_inner_left, .fixed_minimal .header_inner_left{ position:relative; left:auto; top:auto; float:left; } .fixed_minimal .container_inner .logo_wrapper, .fixed_minimal .logo_wrapper{ float:none; position:absolute; left:50%; top:0; } @media only screen and (min-width: 1000px){ .fixed_minimal .q_logo a img{ -webkit-transform: translate(-50%, 0px); -moz-transform: translate(-50%, 0px); -ms-transform: translate(-50%, 0px); -o-transform: translate(-50%, 0px); transform: translate(-50%, 0px); } } .fixed_minimal .popup_menu .line:after, .fixed_minimal .popup_menu .line:before{ z-index:1; } .fixed_minimal .side_menu_button > a{ margin:0; } /* Fixed Minimal header type styles end ========================================================================== */ /* Fixed Top Header header type styles ========================================================================== */ .fixed_top_header .top_header{ background-color: #fff; position:fixed; z-index:110; width:100%; left:0; top:0; -webkit-backface-visibility: hidden; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .fixed_top_header .top_header .left{ float:left; } .fixed_top_header .top_header .right{ float:right; } .fixed_top_header .top_header nav.main_menu{ position:relative; left:0; } .fixed_top_header .top_header nav.main_menu > ul{ left:0; } .fixed_top_header .header_inner_center{ text-align:center; } .fixed_top_header .logo_wrapper{ float:none; padding:25px 0 25px 0; } .fixed_top_header .q_logo{ top:0; } .fixed_top_header .q_logo a{ display:inline-block; vertical-align:middle; } .fixed_top_header .q_logo a img{ top: 0; left:0; -webkit-transform: translate(-50%, 0px); -moz-transform: translate(-50%, 0px); -ms-transform: translate(-50%, 0px); -o-transform: translate(-50%, 0px); transform: translate(-50%, 0px); } .fixed_top_header .side_menu_button, .fixed_top_header .shopping_cart_inner, .fixed_top_header .header_bottom_right_widget_holder{ height:45px; } .fixed_top_header nav.main_menu > ul > li > a{ line-height:45px; } .fixed_top_header.has_top .bottom_header{ padding-top: 45px; } .fixed_top_header .bottom_header{ background-color: #fff; } .fixed_top_header .header_bottom_center_widget{ padding-bottom:20px; } .fixed_top_header .top_header .header-widget{ float:left; } .fixed_top_header nav.mobile_menu{ background-color: #fff; } .fixed_top_header .qode_search_form_3 .qode_search_close{ font-size:25px; } .fixed_top_header .qode_search_form_3{ position:fixed; left:0; top:0; } .fixed_top_header .top_header > .left{ padding-left:45px; } .fixed_top_header .top_header > .right{ padding-right:45px; } .fixed_top_header .top_header .container_inner .left, .fixed_top_header .top_header .container_inner .right{ padding-left:0; padding-right:0; } .fixed_top_header.light .header_bottom_center_widget{ color: #fff; } .fixed_top_header.dark .header_bottom_center_widget{ color: #000; } header.fixed_top_header .top_header nav.main_menu > ul > li:first-child > a { padding-left: 0; } /* Fixed Top Header header type styles end ========================================================================== */ .mobile_menu_button{ display: none; float: left; height: 100px; margin: 0 20px 0 0; } .mobile_menu_button span { color: #777; width: 19px; height: 17px; font-size: 14px; z-index: 50; display: table-cell; position: relative; cursor: pointer; vertical-align: middle; } .dark .mobile_menu_button span{ color: #000; } nav.mobile_menu{ display: none; width: 100%; float: left; position: relative; top: 0px; text-align: left; overflow: hidden; background-color: #fff; z-index: 100; } nav.mobile_menu ul{ display: none; width: 100%; position: relative; list-style: none; padding: 0; margin: 0; } nav.mobile_menu > ul{ margin-bottom: -1px !important; } nav.mobile_menu ul li{ margin: 0px; padding: 0px; position: relative; } nav.mobile_menu ul li a{ -webkit-transition: all 0.2s ease; -moz-transition: all 0.2s ease; -o-transition: all 0.2s ease; -webkit-tap-highlight-color: transparent; } nav.mobile_menu ul li, nav.mobile_menu ul li, nav.mobile_menu ul li ul li { border-bottom: 1px solid #eaeaea; } nav.mobile_menu ul li.open_sub > ul { border-top: 1px solid #eaeaea; } nav.mobile_menu ul li:last-child{ border: 0px !important; } nav.mobile_menu ul > li.has_sub > span.mobile_arrow, nav.mobile_menu ul > li.has_sub > span.mobile_arrow { cursor: pointer; display: inline-block; float: right; height: 46px; line-height: 46px; margin: 0px; padding: 0px 10px 0px 0px; position: absolute; top: 0px; right: 0px; text-align: right; width: 50px; z-index: 9000; -webkit-tap-highlight-color: transparent; } nav.mobile_menu ul li span.mobile_arrow i, nav.mobile_menu ul li span.mobile_arrow i{ color: #888; } nav.mobile_menu ul > li > span.mobile_arrow i{ display:none; } nav.mobile_menu ul > li.has_sub > span.mobile_arrow i{ display:inline; } nav.mobile_menu ul > li.has_sub > span.mobile_arrow i.fa-angle-down, nav.mobile_menu ul > li.has_sub > span.mobile_arrow i.fa-angle-down{ display:none; } nav.mobile_menu ul > li.has_sub.open_sub > span.mobile_arrow i.fa-angle-right, nav.mobile_menu ul > li.has_sub > ul.open_sub > li > span.mobile_arrow i.fa-angle-right{ display:none; } nav.mobile_menu ul > li.has_sub.open_sub > span.mobile_arrow i.fa-angle-down, nav.mobile_menu ul > li.has_sub ul.open_sub > li > span.mobile_arrow i.fa-angle-down{ display:inline; } nav.mobile_menu ul li a, nav.mobile_menu ul li h3{ font-size: 13px; font-weight: 400; color: #888; padding: 10px 0px 10px 0; display: block; position: relative; text-transform: none; line-height: 26px; letter-spacing: 0; } nav.mobile_menu ul li a:hover, nav.mobile_menu ul li.active > a{ color: #1abc9c; } nav.mobile_menu ul li ul li{ margin: 0px 0px 0px 20px; } header:not(.centered_logo) .header_fixed_right_area { position: absolute; right: 0; top: 0; height: 100%; line-height:100px; } .header_menu_bottom .main_menu{ left: auto; } .sticky .header_menu_bottom .main_menu{ float: right; left: auto; position: relative; } .sticky .header_menu_bottom .main_menu_header_inner_right_holder .main_menu{ float:left; } .sticky .header_menu_bottom .main_menu_header_inner_right_holder.with_center_logo .main_menu{ float:left; } .sticky .header_menu_bottom .main_menu_header_inner_right_holder{ float:right; } .header_menu_bottom nav.main_menu > ul{ left: auto; } .sticky .header_menu_bottom nav.main_menu > ul{ left: auto; } .side_menu_button_wrapper{ display: table; } .side_menu_button{ cursor: pointer; display: table-cell; vertical-align: middle; height: 100px; } .header_bottom_right_widget_holder{ display: table-cell; vertical-align: middle; height: 100%; padding:0 17px; } @media only screen and (min-width: 1000px){ header.dark:not(.sticky):not(.scrolled) .header_bottom_right_widget_holder a.qbutton, header.dark.header_style_on_scroll .header_bottom_right_widget_holder a.qbutton{ border-color:#000 !important; background-color: transparent !important; color:#000 !important; } header.light:not(.sticky):not(.scrolled) .header_bottom_right_widget_holder a.qbutton, header.light.header_style_on_scroll .header_bottom_right_widget_holder a.qbutton{ border-color:#fff !important; background-color: transparent !important; color:#fff !important; } } /*header.has_woocommerce_dropdown .side_menu_button > a { top: -8px; }*/ .side_menu_button > a { font-size: 14px; position: relative; display: inline; width: 20px; height: 20px; padding:0 12px; } .side_menu_button > a.side_menu_button_link.medium { display: inline-block; font-size: 21px; line-height: 30px; height: 30px; width: 19px; } .side_menu_button > a.side_menu_button_link.large { display: inline-block; font-size: 28px; line-height: 34px; height: 34px; width: 24px; } .side_menu_button > a, .mobile_menu_button span { -webkit-transition: opacity 0.3s ease; -moz-transition: opacity 0.3s ease; -ms-transition: opacity 0.3s ease; -o-transition: opacity 0.3s ease; color: #9d9d9d; } .side_menu_button > a:hover, .mobile_menu_button span:hover { opacity: 0.8; } .light:not(.sticky):not(.scrolled) .header-widget .q_social_icon_holder i.simple_social, .light:not(.sticky):not(.scrolled) .header-widget, .light:not(.sticky):not(.scrolled) .header-widget.widget_nav_menu ul.menu > li > a, .light:not(.sticky):not(.scrolled) .header-widget p, .light:not(.sticky):not(.scrolled) .header-widget a, .light:not(.sticky):not(.scrolled) .header-widget span, .light.header_style_on_scroll .header-widget .q_social_icon_holder i.simple_social, .light.header_style_on_scroll .header-widget, .light.header_style_on_scroll .header-widget.widget_nav_menu ul.menu > li > a, .light.header_style_on_scroll .header-widget p, .light.header_style_on_scroll .header-widget a, .light.header_style_on_scroll .header-widget span{ color:#fff; } .light:not(.sticky):not(.scrolled) .header-widget .q_social_icon_holder i.simple_social, .light:not(.sticky):not(.scrolled) .header-widget #lang_sel > ul > li > a, .light:not(.sticky):not(.scrolled) .header-widget #lang_sel_click > ul > li> a, .light.header_style_on_scroll .header-widget .q_social_icon_holder i.simple_social, .light.header_style_on_scroll .header-widget #lang_sel > ul > li > a, .light.header_style_on_scroll .header-widget #lang_sel_click > ul > li> a{ color:#fff !important; } .dark:not(.sticky):not(.scrolled) .q_social_icon_holder i.simple_social, .dark:not(.sticky):not(.scrolled) .header-widget, .dark:not(.sticky):not(.scrolled) .header-widget.widget_nav_menu ul.menu > li > a, .dark:not(.sticky):not(.scrolled) .header-widget p, .dark:not(.sticky):not(.scrolled) .header-widget a, .dark:not(.sticky):not(.scrolled) .header-widget span, .dark.header_style_on_scroll .q_social_icon_holder i.simple_social, .dark.header_style_on_scroll .header-widget, .dark.header_style_on_scroll .header-widget.widget_nav_menu ul.menu > li > a, .dark.header_style_on_scroll .header-widget p, .dark.header_style_on_scroll .header-widget a, .dark.header_style_on_scroll .header-widget span{ color:#000; } .dark:not(.sticky):not(.scrolled) .header-widget .q_social_icon_holder i.simple_social, .dark:not(.sticky):not(.scrolled) .header-widget #lang_sel > ul > li > a, .dark:not(.sticky):not(.scrolled) .header-widget #lang_sel_click > ul > li> a, .dark.header_style_on_scroll .header-widget .q_social_icon_holder i.simple_social, .dark.header_style_on_scroll .header-widget #lang_sel > ul > li > a, .dark.header_style_on_scroll .header-widget #lang_sel_click > ul > li> a{ color:#000 !important; } .side_menu_button a:last-child{ padding: 0px 0px 0px 8px; } .header_inner_right.left_side .side_menu_button a:last-child{ padding: 0px; } header.sticky .header_inner_right.left_side{ display:none; } .side_menu .q_font_awsome_icon .qode_icon_element { color:#818181; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; margin:0 8px 0 0; -webkit-backface-visibility: visible; /* fix the problem with boxed background on Chrome */ } .side_menu li:hover .q_font_awsome_icon .qode_icon_element{ color:#fff; } .q_slider { width: 100%; overflow: hidden; position: relative; z-index: 10; } .ls-wp-fullwidth-helper { left: 0px !important; } /*.content{ margin-top: 0; position: relative; z-index: 100; background-color: #f6f6f6; } .content.content_top_margin{ margin-top: 100px !important; } .content.content_top_margin_none{ margin-top: 0 !important; }*/ .container{ position: relative; padding: 0; width: 100%; z-index:100; } .container_inner{ width: 1100px; margin: 0px auto; } /*.content .container { background-color: #f6f6f6; } .content .container .container_inner{ padding:0px 0px 0px 0px; } .content .container .container_inner.page_container_inner{ padding:30px 0px 0px 0px; }*/ .full_page_container_inner{ padding:30px 0px 0px 0px; } .full_width{ position: relative; z-index: 100; background-color: #f6f6f6; } .header_bottom .container_inner{ position: relative; } /*.content .title .container_inner{ padding: 0px !important; }*/ section.section{ display: block; position: relative; padding: 50px 0; overflow: hidden; } div.section{ position:relative; background-position: center center; background-repeat: no-repeat; background-size: cover; } .use_row_as_box{ -moz-border-radius:4px; -webkit-border-radius:4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius:4px; } .vc_row.disable_negative_margin { margin-left: 0; margin-right: 0; } div.video_section{ overflow: hidden; } .boxed .section .section_inner, .grid_section .section_inner{ width: 1100px; margin: 0px auto; position: relative; z-index: 20; } .full_section_inner{ position: relative; z-index: 20; } /* Section Video Background - Start */ .section .mobile-video-image { background-position: center center; background-repeat: no-repeat; background-size: cover; display: none; height: 100%; left: 0; position: absolute; top: 0; width: 100%; z-index: 10; } .section .video-overlay { height: 3000px; left: 0; opacity: 0; position: absolute; top: 0; width: 100%; z-index: 11; } .section .video-overlay.active { background-image: url("img/pixel-video.png"); background-position: 0px 0px; background-repeat: repeat; opacity: 1; } .section .video-wrap { top: 0px; left: 0px; overflow: hidden; position: absolute; width: 100%; z-index: 10; } .section .video-wrap .mejs-poster { background-size: cover!important; -moz-background-size: cover!important; -webkit-background-size: cover!important; -o-background-size: cover!important; } .section .video-wrap .mejs-container .mejs-controls { display: none!important; } .section .video-wrap .mejs-controls .mejs-button button:focus { outline: none!important; } .section .video-wrap .mejs-controls .mejs-time-rail .mejs-time-loaded { background-color: rgba(255, 255, 255, 0.18) !important; } .section .video-wrap .mejs-container { background-color: transparent!important; background-image: none!important; height: auto !important; } .section .video-wrap .mejs-mediaelement{ background: none !important; border: 0px !important; } .section .video-wrap .mejs-container .mejs-poster img { max-width: none!important; width: 100%!important; } .section .video-wrap .mejs-controls button { opacity: 0.8; } .section .video-wrap .mejs-controls button:hover, .mejs-controls .mejs-fullscreen-button:hover button { opacity: 1!important;} .section .video-wrap .mejs-controls .mejs-time-rail .mejs-time-total { background: #1f1f1f none repeat scroll 0 0 !important; } .section .video-wrap .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current { background: transparent!important; } /* Section Video Background - End */ .two_columns_66_33{ width: 100%; } .two_columns_66_33>.column1{ width: 66.66%; float: left; } .two_columns_66_33>.column1>.column_inner{ padding: 0 20px 0 0; } .two_columns_66_33>.column2{ width: 33.33%; float: left; } .two_columns_66_33>.column2>.column_inner{ padding: 0 0 0 20px; } .two_columns_33_66{ width: 100%; } .two_columns_33_66>.column1{ width: 33.33%; float: left; } .two_columns_33_66>.column1>.column_inner{ padding: 0 20px 0 0; } .two_columns_33_66>.column2{ width: 66.66%; float: left; } .two_columns_33_66>.column2>.column_inner{ padding: 0 0 0 20px; } .two_columns_75_25{ width: 100%; } .two_columns_75_25>.column1{ width: 75%; float: left; } .two_columns_75_25>.column1>.column_inner{ padding: 0 20px 0 0; } .two_columns_75_25>.column2{ width: 25%; float: left; } .two_columns_75_25>.column2>.column_inner{ padding: 0 0 0 20px; } .two_columns_25_75 { width: 100%; } .two_columns_25_75>.column1{ width: 25%; float: left; } .two_columns_25_75>.column1>.column_inner{ padding: 0 20px 0 0; } .two_columns_25_75>.column2{ width: 75%; float: left; } .two_columns_25_75>.column2>.column_inner{ padding: 0 0 0 20px; } .two_columns_50_50 { width: 100%; } .two_columns_50_50>.column1{ width: 50%; float: left; } .two_columns_50_50>.column1>.column_inner{ padding: 0 10px 0 0; } .two_columns_50_50>.column2{ width: 50%; float: left; } .two_columns_50_50>.column2>.column_inner{ padding: 0 0 0 10px; } .three_columns { width: 100%; } .three_columns>.column1, .three_columns>.column2, .three_columns>.column3{ width: 33.33%; float: left; } .three_columns>.column1>.column_inner{ padding: 0 15px 0 0; } .three_columns>.column2>.column_inner{ padding: 0 5px 0 10px; } .three_columns>.column3>.column_inner{ padding: 0 0 0 15px; } .four_columns{ width: 100%; } .four_columns>.column1, .four_columns>.column2, .four_columns>.column3, .four_columns>.column4{ width: 25%; float: left; } .four_columns>.column1>.column_inner{ padding: 0 15px 0 0; } .four_columns>.column2>.column_inner{ padding: 0 10px 0 5px; } .four_columns>.column3>.column_inner{ padding: 0 5px 0 10px; } .four_columns>.column4>.column_inner{ padding: 0 0 0 15px; } .five_columns>.column1, .five_columns>.column2, .five_columns>.column3, .five_columns>.column4, .five_columns>.column5{ width: 20%; float: left; } .five_columns>.column1>.column_inner, .five_columns>.column2>.column_inner, .five_columns>.column3>.column_inner, .five_columns>.column4>.column_inner{ margin: 0 2.5% 0 0; } .five_columns>.column5>.column_inner{ margin: 0; } .title_outer.animate_title_area{ overflow: hidden; } /*.title{ display: block; width: 100%; height: 100px; text-align: left; position: relative; z-index: 101; border-bottom-color:#eee; }*/ .title_outer.with_image .title{ height: auto !important; line-height: normal; background: none; } .title img{ display: block; position: relative; width: 100%; } .title .not_responsive{ display: none; } .title .title_holder{ display: table; height: 100%; left: 0; position: relative; width: 100%; } .title_outer.with_image .title .title_holder, .title_outer .has_fixed_background.title .title_holder, .title_outer .has_background.title .title_holder { position: absolute; top: 0%; display:block; } .title .title_overlay{ position: absolute; width: 100%; height: 100%; background-repeat: repeat; background-position: 0px 0px; top: 0; } .title .title_holder .container{ display: table-cell; vertical-align: middle; background-color: transparent; } .title_outer.with_image .title .title_holder .container, .title_outer .has_fixed_background.title .title_holder .container, .title_outer .has_background.title .title_holder .container { display:block; height: 100%; } .content .title_outer.with_image .title .container_inner, .title_outer .has_fixed_background.title .title_holder .container_inner, .title_outer .has_background.title .title_holder .container_inner { display: table; height: 100%; } .title_subtitle_holder{ display: block; padding: 0px; position:relative; } .title_outer.with_image .title .title_subtitle_holder, .title_outer .has_fixed_background.title .title_subtitle_holder, .title_outer .has_background.title .title_subtitle_holder { display: table-cell; vertical-align: middle; width: 100%; } .title_subtitle_holder_inner { position: relative; } .title h1{ color: #303030; padding: 0px; text-transform:uppercase; letter-spacing:1px; font-weight: 600; } .title.title_size_medium h1{ font-size: 24px; line-height: 1.384615384615385em; } .title.title_size_small h1, .title h1 { font-size: 17px; line-height: 1.304347826086957em; } .title.title_size_large h1{ font-size: 47px; line-height: 60px; } .title_text_shadow .title h1{ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); } .subtitle{ display:block; } .title_text_shadow .subtitle{ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); } .animate_title_text .title h1{ -webkit-animation: title-from-right .5s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275) 1s; -moz-animation: title-from-right .5s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275) 1s; -o-animation: title-from-right .5s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275) 1s; animation: title-from-right .5s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275) 1s; -webkit-animation-fill-mode: both; -moz-animation-fill-mode: both; -ms-animation-fill-mode: both; -o-animation-fill-mode: both; animation-fill-mode: both; visibility: visible; } @-webkit-keyframes title-from-right { 0% { filter: alpha(opacity=0); opacity: 0; -webkit-transform: translate(50%, 0); } 100% { filter: alpha(opacity=100); opacity: 1; -webkit-transform: translate(0, 0); } } @-moz-keyframes title-from-right { 0% { filter: alpha(opacity=0); opacity: 0; -moz-transform: translate(50%, 0); } 100% { filter: alpha(opacity=100); opacity: 1; -moz-transform: translate(0, 0); } } @-o-keyframes title-from-right { 0% { filter: alpha(opacity=0); opacity: 0; -o-transform: translate(50%, 0); } 100% { filter: alpha(opacity=100); opacity: 1; -o-transform: translate(0, 0); } } @keyframes title-from-right { 0% { filter: alpha(opacity=0); opacity: 0; transform: translate(50%, 0); } 100% { filter: alpha(opacity=100); opacity: 1; transform: translate(0, 0); } } .position_center.title .title_subtitle_holder{ text-align:center; } .position_right.title .title_subtitle_holder{ text-align:right; } .position_right .breadcrumb{ left:0; right: auto; } .title.has_background { background-repeat: no-repeat; background-position: center 0; } .title.has_fixed_background { background-repeat: no-repeat; background-attachment: fixed; background-position: center 0; position: relative; z-index: 101; } .breadcrumb{ position:absolute; height:100%; font-size:13px; top:0; right:0; color:#303030; } .breadcrumbs{ display:table; height:100%; width:100%; line-height: 1em; } .breadcrumbs .breadcrumbs_inner{ display:table-cell; vertical-align:middle; } .title_text_shadow .breadcrumbs .breadcrumbs_inner{ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); } .position_center.title .breadcrumb{ position:relative; text-align:center; } .title .separator.small, .title .separator.small.left, .title .separator.small.right { margin-top: 14px; margin-bottom: 10px; } .title_border_in_grid_holder{ height: 1px; width: 1100px; margin: 0 auto; background-color: #eee; } .breadcrumb .current{ color:#303030; } .breadcrumb a{ color:#303030; } .breadcrumb a:hover{ color:#1abc9c; } .touch .title.has_fixed_background { background-attachment: scroll; } .box_image_with_border{ display: block; position: relative; border-bottom: 5px solid #dddddd; -webkit-transition: all .4s ease-out 0s; -moz-transition: all .4s ease-out 0s; -o-transition: all .4s ease-out 0s; -ms-transition: all .4s ease-out 0s; text-align: center; } .box_image_with_border:hover{ border-color: #1abc9c; } .box_image_with_border h3{ margin: 0 0 15px; } .box_image_holder{ display: block; position: relative; margin: 0 0 56px; text-align: left; } .box_image_holder a{ position: relative; display: block; } .box_image_holder .box_image_shadow{ display: block; position: absolute; bottom: -8px; left: 0; width: 100%; height: 100%; background-image: url('img/box_image_shadow.png'); background-repeat: no-repeat; background-position: center bottom; background-size: 100% 30px; -webkit-background-size: 100% 30px; -moz-background-size: 100% 30px; -o-background-size: 100% 30px; -webkit-transition: all .4s ease-out 0s; -moz-transition: all .4s ease-out 0s; -o-transition: all .4s ease-out 0s; -ms-transition: all .4s ease-out 0s; } .box_image_with_border:hover .box_image_shadow{ bottom: -13px; opacity: 0.2; filter: alpha(opacity=20); } .box_image_holder .image_holder_inner{ position: relative; display: inline-block; width: 100%; top: 0px; left: 0px; -webkit-transition: all .4s ease-out 0s; -moz-transition: all .4s ease-out 0s; -o-transition: all .4s ease-out 0s; -ms-transition: all .4s ease-out 0s; } .box_image_with_border:hover .box_image_holder .image_holder_inner{ top: -15px; } .box_image_holder img{ width: 100%; } .box_image_holder .box_icon{ display: inline-block; position: absolute; left: 50%; bottom: 0px; -webkit-transform: translateZ(0px); -moz-transform: translateZ(0px); } .box_image_holder .box_icon .fa-stack{ margin: 0 0 0 -50%; font-size: 4em; } .box_image_holder .box_icon .fa-stack i{ margin: 35% 0 0; } .box_image_holder .box_icon .fa-stack i.fa-stack-base { color: #1abc9c; } .separator { position: relative; display: block; height: 1px; background-color: #eaeaea; margin: 10px 0; } .separator.transparent { background-color: transparent; } .separator.small { background-color: #303030; height: 2px; position: relative; width: 22px; display: block; margin: 10px auto 20px auto; } .wpb_column > .wpb_wrapper .separator.small { margin-bottom: 20px; } .separator.small.left { margin: 10px 0 20px 0; } .separator.small.right { margin: 10px 0 20px auto; } /* ========================================================================== Icon list shortcode styles ========================================================================== */ .q_icon_list { margin-bottom: 21px; } .q_icon_list p{ font-size: 15px; line-height: 27px; font-weight: 400; margin: 0 0 10px; padding: 0 0 0 38px; position: relative; color: #303030; } .q_icon_list i { background-color: #1abc9c; color: #fff; font-size: 18px; line-height: 27px; height: 27px; width: 27px; text-align: center; border-radius: 2em; -webkit-border-radius: 2em; -moz-border-radius: 2em; -o-border-radius: 2em; } .q_icon_list i.transparent { background: transparent; border: 0; color: #ababab; } /* ========================================================================== Progress bar shortcode start styles ========================================================================== */ .q_progress_bar { position: relative; margin: 0 0 28px 0; width: 100%; overflow: hidden; text-align: left; } .q_progress_bar .progress_content_outer{ background-color: #e3e3e3; position: relative; overflow: hidden; height: 13px; } .q_progress_bar .progress_content{ position: absolute; top: 0; left: 0; max-width: 100%; overflow: hidden; background-color: #1abc9c; height: 13px; box-sizing: border-box; } .q_progress_bar .progress_title_holder { position: relative; margin: 0 0 7px 0; } .q_progress_bar .progress_title { display: inline-block; z-index: 100; } .q_progress_bar .progress_number_wrapper { text-align: right; position: absolute; left: 0px; z-index: 10; opacity: 0; filter: alpha(opacity=0); color: #fff; } .q_progress_bar .progress_number { position: absolute; right: 0; font-size: 18px; font-weight: 500; top: -1px; } /* ========================================================================== Progress bar shortcode end styles ========================================================================== */ /* ========================================================================== Vertical progress bar shortcode start styles ========================================================================== */ .q_progress_bars_vertical .progress_content_outer { height: 200px; position: relative; background-color: #e3e3e3; } .q_progress_bars_vertical .progress_number { font-size: 18px; line-height: 1em; color: #303030; display: block; position: relative; font-weight: 500; margin-bottom: 14px; } .q_progress_bars_vertical .progress_title { margin-bottom: 0.7777777777777778em; margin-top: 1em; } .q_progress_bars_vertica .progress_text { display: inline-block; line-height: 18px; } .q_progress_bars_vertical .progress_content_outer .progress_content { display: inline-block; width: 100%; position: absolute; bottom: 0; left: 0px; background-color: #1abc9c; box-sizing: border-box; } /* ========================================================================== Vertical progress bar shortcode end styles ========================================================================== */ /* ========================================================================== Counter shortcode start styles ========================================================================== */ .q_counter_holder { display: block; opacity: 0; filter: alpha(opacity=0); -webkit-transition: opacity .4s ease 0s; -moz-transition: opacity .4s ease 0s; -o-transition: opacity .4s ease 0s; padding: 20px 0; } .q_counter_holder.boxed_counter { border: 1px solid #eaeaea; padding: 20px 40px; background-color:#fff; } .q_counter_holder.left { text-align: left; } .q_counter_holder.right { text-align: right; } .q_counter_holder.center { text-align: center; padding: 20px 40px; } .q_counter_holder span.counter { font-size: 60px; line-height: 1em; font-weight: 300; color: #1abc9c; display: inline-block !important; height: 1em; } .q_counter_holder p.counter_text { font-weight: 600; text-transform: uppercase; letter-spacing:1px; margin: 12px 0 0 00; } .q_counter_holder .separator.small { background-color: #eaeaea; margin: 19px auto 0px auto; } .q_counter_holder.left .separator.small { margin-left: 0; margin-right: auto; } .q_counter_holder.right .separator.small { margin-left: auto; margin-right: 0; } /* ========================================================================== Counter shortcode end styles ========================================================================== */ /* ========================================================================== Box Holder shortcode start styles ========================================================================== */ .q_box_holder{ display: block; position: relative; border: 1px solid transparent; z-index: 200; } .q_box_holder.with_icon{ border: 2px solid #c0c0c0; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; } .box_holder_inner{ padding: 30px 20px; display: block; } .q_box_holder.with_icon .box_holder_inner.tiny{ padding: 37px 20px 30px; } .q_box_holder.with_icon .box_holder_inner.small{ padding: 45px 20px 30px; } .q_box_holder.with_icon .box_holder_inner.medium{ padding: 58px 20px 30px; } .q_box_holder.with_icon .box_holder_inner.large{ padding: 71px 20px 30px; } .q_box_holder.with_icon .box_holder_inner.very_large{ padding: 85px 20px 30px; } .box_holder_inner.left{ text-align: left; } .box_holder_inner.right{ text-align: right; } .box_holder_inner.center{ text-align: center; } .box_holder_icon{ position: absolute; display: block; left: 50%; top: 0; z-index: 250; } .box_holder_icon_inner{ margin: -50% 0 0 -50%; } .box_holder_icon_inner.circle, .box_holder_icon_inner.square, .box_holder_icon_inner.image{ margin: -50% 0 0 -50%; } .box_holder_icon_inner.circle .fa-stack, .circle .icon_holder .fa-stack{ -o-border-radius: 2em; -moz-border-radius: 2em; -webkit-border-radius: 2em; -ms-border-radius: 2em; border-radius: 2em; } .box_holder_icon .fa-stack i{ color: #1abc9c; } .box_holder_icon_inner.tiny i.fa-circle{ font-size: 40px; } .box_holder_icon_inner.image.tiny img{ height: 35px; } .box_holder_icon_inner.image.small img{ height: 52px; } .box_holder_icon_inner.image.medium img{ height: 78px; } .box_holder_icon_inner.image.large img{ height: 104px; } .box_holder_icon_inner.image.very_large img{ height: 130px; } /* ========================================================================== Box Holder shortcode end styles ========================================================================== */ /* ========================================================================== Button shortcode start styles ========================================================================== */ .qbutton, .load_more a, .blog_load_more_button a, #submit_comment, .drop_down .wide .second ul li .qbutton, .drop_down .wide .second ul li ul li .qbutton { position: relative; display: inline-block; width: auto; height: 39px; line-height: 39px; margin: 0; padding: 0px 23px; border: 2px solid #303030; font-size: 13px; font-weight: 700; font-family: inherit; text-align: left; color: #303030; text-decoration: none; cursor: pointer; white-space: nowrap; outline: none; font-style: normal; text-transform: uppercase; letter-spacing: 1px; -o-border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; text-shadow: none; background-color: transparent; -webkit-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -moz-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -ms-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -o-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -webkit-box-sizing: initial !important; -moz-box-sizing: initial !important; box-sizing: initial !important; } input.qbutton { line-height: 36px; } .qbutton:hover, .load_more a:hover, .blog_load_more_button a:hover, #submit_comment:hover, .drop_down .wide .second ul li .qbutton:hover, .drop_down .wide .second ul li ul li .qbutton:hover{ background-color: #1abc9c; border-color: #1abc9c; color: #fff; text-decoration: none; } .qbutton.left { text-align: left; } .qbutton.right { text-align: right; } .qbutton.center { text-align: center; } /* Button sizes styles ========================================================================== */ .qbutton.big_large{ height: 58px; line-height: 58px; font-size: 20px; padding: 0 22px; } .qbutton.big_large_full_width{ width:100%; height: 90px; line-height: 90px; font-size: 20px; padding:0; text-align: center; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -o-box-sizing: border-box; } .qbutton.large { height: 47px; line-height: 47px; font-size: 16px; padding: 0px 29px; } .qbutton.small { height: 30px; line-height: 30px; font-size: 12px; padding:0 17px; } /* Button color styles ========================================================================== */ .qbutton.white { border-color: #fff; color:#fff; } .qbutton.white:hover { background-color: #1abc9c; border-color: #1abc9c; } .qbutton.green { border-color: #1abc9c; color:#fff; background-color: #1abc9c; } .qbutton.green:hover { background-color: #fff; border-color: #fff; color: #a2a2a2; } /* Button with icon styles ========================================================================== */ .qbutton i { margin: 0 0 0 10px; } .qbutton.large i { margin: 0 0 0 17px; } .qbutton.medium i { margin: 0 0 0 15px; } .qbutton.small i { margin: 0 0 0 10px; } .qbutton.tiny i { margin: 0 0 0 8px; } .qbutton.big_large i, .qbutton.big_large_full_width i { margin: 0 0 0 19px; } /* Button usage custom styles ========================================================================== */ #submit_comment, .load_more.tiny a { height: 39px; line-height: 39px; font-size: 12px; padding: 0px 18px; } #submit_comment { line-height: 36px; } /* ========================================================================== Button end styles ========================================================================== */ /* ========================================================================== Pie Charts and Pie Charts With Icon start styles ========================================================================== */ .easyPieChart { position: relative; } .easyPieChart canvas { position: absolute; top: 0; left: 0; } .q_pie_chart_holder, .q_pie_chart_with_icon_holder{ display: block; margin: 0 0 30px; opacity: 0; filter: alpha(opacity=0); -webkit-transition: opacity .3s ease 0s; -moz-transition: opacity .3s ease 0s; -o-transition: opacity .3s ease 0s; } .q_percentage { font-size: 35px; font-weight: 500; color: #303030; text-align: center; margin: 0 auto; opacity: 0; filter: alpha(opacity=0); -webkit-transition: opacity .3s ease 0s; -moz-transition: opacity .3s ease 0s; -o-transition: opacity .3s ease 0s; } .q_percentage_with_icon{ color: #1abc9c; text-align: center; margin: 0 auto; opacity: 0; filter: alpha(opacity=0); -webkit-transition: opacity .3s ease 0s; -moz-transition: opacity .3s ease 0s; -o-transition: opacity .3s ease 0s; -webkit-backface-visibility: hidden; } .q_pie_chart_holder .tocounter{ float: none; margin: 0; } .q_percentage_with_icon i{ float: none; margin: 0; vertical-align: middle !important; color: #b9b9b9; } .q_pie_chart_holder .pie_chart_text, .q_pie_chart_with_icon_holder .pie_chart_text{ text-align: center; margin: 28px 0 0; } .q_pie_chart_holder .pie_chart_text .pie_title, .q_pie_chart_with_icon_holder .pie_chart_text .pie_title{ margin: 0 0 0.35em; } .q_pie_chart_holder .separator.small { background-color: #eaeaea; margin: 10px auto 12px auto; } /* ========================================================================== Pie Charts and Pie Charts With Icon end styles ========================================================================== */ /* ========================================================================== Image With Text start styles ========================================================================== */ .image_with_text { display: inline-block; width: 100%; position: relative; } .image_with_text img { display: block; margin: 0 0 22px 0; } /* ========================================================================== Image With Text end styles ========================================================================== */ /* ========================================================================== Call to action styles ========================================================================== */ .call_to_action { position: relative; display: block; padding: 51px 21px; background-color: #1abc9c; } .call_to_action .two_columns_75_25 { position: relative; } .call_to_action .text_wrapper { position:relative; } .call_to_action .text_wrapper .call_to_action_text { color: #fff; letter-spacing: 1px; font-size: 22px; font-weight: 500; } .call_to_action.with_icon .text_wrapper .call_to_action_text { padding:0 0 0 54px; line-height: 1em; } .call_to_action .text_wrapper .call_to_action_icon_holder{ position:absolute; height:100%; } .call_to_action .text_wrapper .call_to_action_icon{ display:table; height:100%; } .call_to_action .text_wrapper .call_to_action_icon_inner { display:table-cell; height:100%; vertical-align:middle; } .call_to_action .text_wrapper .call_to_action_icon_inner i { color: #fff; } .call_to_action .column2.button_wrapper { text-align: right; } .call_to_action .column2.button_wrapper .qbutton{ position:absolute; right:0; top:50%; margin:-21px 0 0 0; } .call_to_action .column2.button_wrapper .qbutton.small{ margin-top:-17px; } .call_to_action .column2.button_wrapper .qbutton.large{ margin-top:-25px; } .call_to_action .column2.button_wrapper .qbutton.big_large{ margin-top:-31px; } /* ========================================================================== Parallax shortcode styles ========================================================================== */ .full_width .parallax_content{ width: 1100px; margin: 0px auto; } section.section section.parallax{ margin: -50px 0px; } .boxed section.section section.parallax{ margin: -50px -25px; } .boxed .full_width .parallax_content{ width: auto; margin: 0px; padding: 0px 25px; } section.parallax_section_holder{ position: static; padding: 0px; background-repeat: no-repeat; background-color: transparent; background-position: center 0px; background-attachment: fixed; overflow: hidden; } .parallax_content, .parallax_content_full_width { z-index: 100; position: relative; } .parallax_content.left, .parallax_content_full_width.left{ text-align: left; } .parallax_content.center, .parallax_content_full_width.center{ text-align: center; } .parallax_content.right, .parallax_content_full_width.right{ text-align: right; } /* ========================================================================== Portfolio styles ========================================================================== */ .portfolio_single{ display: block; position: relative; } .portfolio_single_text_holder, .portfolio_detail, .lightbox_single_portfolio{ position: relative; } .portfolio_single .flexslider, .portfolio_single .portfolio_single_text_holder{ margin: 0 0 40px; } .portfolio_single .portfolio_images .fluid-width-video-wrapper, .portfolio_single .portfolio_images img{ margin: 0 0 18px; } .portfolio_single a.lightbox_single_portfolio.video_in_lightbox{ display: block; } .portfolio_single a.lightbox_single_portfolio > i{ position: absolute; top: 50%; left: 50%; display: inline-block; vertical-align: middle; font-size: 40px; color: #fff; margin: -20px 0 0 -15px; z-index: 110; } .portfolio_single .portfolio_container{ position: relative; z-index: 200; } .portfolio_single h2{ margin: 0px 0 5px 0; } .portfolio_single h3{ margin: 0px 0 8px 0; } .portfolio_detail.portfolio_single_follow { position: relative; } .portfolio_detail .info{ padding: 0 0 9px; margin: 0 0 9px; } .portfolio_detail .info:last-child{ border: 0px; } .video_holder{ position: relative; width: 100%; display: block; min-height: 1px; } .portfolio_single .video .mobile-video-image { background-position: center center; background-repeat: no-repeat; background-size: cover; display: none; height: 100%; left: 0; position: absolute; top: 0; width: 100%; z-index: 10; } .portfolio_single .video{ margin: 0 0 44px; position: relative; } .portfolio_single .video .video-wrap { overflow: hidden; position: relative; width: 100%; z-index: 10; } .portfolio_single .video .video-wrap .mejs-poster { background-size: cover!important; -moz-background-size: cover!important; -webkit-background-size: cover!important; -o-background-size: cover!important; width: 100% !important; height: 100% !important; } .portfolio_single .video .video-wrap .mejs-container { background-color: transparent!important; background-image: none!important; height: 100% !important; width: 100% !important; overflow: hidden; } .portfolio_single .video .video-wrap .mejs-mediaelement{ background: none !important; border: 0px !important; } .portfolio_single .video .video-wrap .mejs-container .mejs-poster img { max-width: none!important; width: 100%!important; } .portfolio_single .mejs-container .mejs-controls{ visibility: visible !important; } .portfolio_single .mejs-controls .mejs-volume-button .mejs-volume-slider{ display: none !important; } .flexslider .slides .mejs-poster img, .portfolio_slider .portfolio_slides .mejs-poster img{ display: none; } .portfolio_single .flexslider .video .video-wrap{ margin: 0px; } /* Portfolio navigation styles ========================================================================== */ .portfolio_navigation { display: inline-block; width: 100%; text-align: center; padding: 28px 0 50px; z-index: 100; position: relative; } .portfolio_navigation .portfolio_prev, .portfolio_navigation .portfolio_next, .portfolio_navigation .portfolio_button{ display: inline-block; height: 35px; line-height: 35px; } .portfolio_navigation .portfolio_prev{ position: absolute; left: 0; } .portfolio_navigation .portfolio_next{ position: absolute; right: 0; } .portfolio_navigation .portfolio_prev a, .portfolio_navigation .portfolio_next a{ position: relative; display: inline-block; width: 38px; height: 38px; line-height: 38px; margin: 0 11px 0 0; text-align:center; font-size: 18px; color: #b4b4b4; text-decoration: none; text-transform: uppercase; cursor: pointer; white-space: nowrap; border: 2px solid #e5e5e5; outline: none; -o-border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; text-shadow: none; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; } .portfolio_navigation .portfolio_prev a:hover, .portfolio_navigation .portfolio_next a:hover { color: #303030; background-color: #e3e3e3; border-color: #e3e3e3; } .portfolio_navigation .portfolio_button a{ background-image: url('img/portfolio_list_button.png'); background-position: 0 0; background-repeat: no-repeat; width: 19px; display: block; height: 19px; margin: 11px 0 0 0; -webkit-transition: background-image 0.3s ease-in-out; -moz-transition: background-image 0.3s ease-in-out; -ms-transition: background-image 0.3s ease-in-out; -o-transition: background-image 0.3s ease-in-out; transition: background-image 0.3s ease-in-out; } .portfolio_navigation .portfolio_button a:hover{ background-image: url('img/portfolio_list_button_hover.png'); } @media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { .portfolio_navigation .portfolio_button a{ background-image: url('img/portfolio_list_button@1_5x.png'); -o-background-size: 19px 19px; -webkit-background-size: 19px 19px; -moz-background-size: 19px 19px; background-size: 19px 19px; } .portfolio_navigation .portfolio_button a:hover{ background-image: url('img/portfolio_list_button_hover@1_5x.png'); } } @media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { .portfolio_navigation .portfolio_button a{ background-image: url('img/portfolio_list_button@2x.png'); -o-background-size: 19px 19px; -webkit-background-size: 19px 19px; -moz-background-size: 19px 19px; background-size: 19px 19px; } .portfolio_navigation .portfolio_button a:hover{ background-image: url('img/portfolio_list_button_hover@2x.png'); } } .portfolio_navigation .portfolio_prev a:hover, .portfolio_navigation .portfolio_next a:hover{ background-image: url('img/button-bg-px.png') !important; } .portfolio_social_holder{ width:100%; display: inline-block; } .portfolio_single .portfolio_social_holder .portfolio_share, .portfolio_single .portfolio_social_holder .portfolio_like{ display: inline-block; margin: 0; } .portfolio_gallery { display: inline-block; width: 100%; position: relative; margin: 0 0 15px 0; } .portfolio_single .portfolio_gallery{ margin: 0 0 3px 0; } .portfolio_gallery a { position: relative; float: left; display: inline-block; overflow: hidden; -webkit-backface-visibility: hidden; -webkit-transform: translateZ(0px); -moz-transform: translateZ(0px); } .portfolio_gallery a.v2 { width: 49%; margin: 0 2% 2% 0; } .portfolio_gallery a.v3 { width: 32%; margin: 0 2% 2% 0; } .portfolio_gallery a.v4 { width: 23.5%; margin: 0 2% 2% 0; } .portfolio_gallery a.v2:nth-child(2n), .portfolio_gallery a.v3:nth-child(3n), .portfolio_gallery a.v4:nth-child(4n) { margin: 0 0 2% 0; } .portfolio_gallery a img, .portfolio_gallery a frame { position: relative; display: block; width: 100%; z-index: 100; } .portfolio_gallery iframe{ min-height: 200px; } .portfolio_gallery a .gallery_text_holder{ background-color: #000; background-color: rgba(0, 0, 0, 0.50); position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; display: inline-block; z-index: 200; opacity: 0; filter: alpha(opacity=0); visibility: visible; -webkit-transition: opacity .4s; -moz-transition: opacity .4s; -o-transition: opacity .4s; -ms-transition: opacity .4s; } .portfolio_gallery a img{ -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } .portfolio_gallery a:hover .gallery_text_holder{ opacity: 1; filter: alpha(opacity=100); } .portfolio_gallery a .gallery_text_inner{ display: table; text-align: center; vertical-align: middle; width: 100%; height: 100%; } .portfolio_gallery a .gallery_text_inner h6{ display: table-cell; text-align: center; vertical-align: middle; width: 100%; height: 100%; margin: 0; padding: 0px 15px; color: #fff; } .projects_holder_outer{ margin: 0; display: block; width: 100%; } .projects_holder_outer .container .container_inner{ padding: 0px 0px 0px 0px; } .full_width .projects_holder_outer.v6 .hover_text, .full_width .projects_holder_outer.v5 .hover_text, .full_width .projects_holder_outer.v4 .hover_text, .full_width .projects_holder_outer.v5 .standard, .full_width .projects_holder_outer.v6 .standard, .full_width .projects_holder_outer.v4 .standard { width: 95%; margin: 0 auto; } .full_width .section_inner .projects_holder_outer.v6 .hover_text, .full_width .section_inner .projects_holder_outer.v5 .hover_text, .full_width .section_inner .projects_holder_outer.v4 .hover_text, .full_width .section_inner .projects_holder_outer.v5 .standard, .full_width .section_inner .projects_holder_outer.v6 .standard, .full_width .section_inner .projects_holder_outer.v4 .standard { width: 100%; } .full_width .projects_holder_outer.v6 .hover_text.no_space, .full_width .projects_holder_outer.v5 .hover_text.no_space, .full_width .projects_holder_outer.v4 .hover_text.no_space{ width: 100%; margin: 0; } .projects_holder{ font-size: 0.1px; line-height: 0; list-style-type: none; text-align: justify; } .projects_holder:after, .projects_holder:before{ content: ""; display: inline-block !important; width: 100%; } .projects_holder > .mix{ /*display: none;*/ visibility: hidden; position: relative; vertical-align: top; -webkit-transition: all 0.7s ease-out; -moz-transition: all 0.7s ease-out; -o-transition: all 0.7s ease-out; transition: all 0.7s ease-out; text-align: left; } .projects_holder.hideItems > .mix{ display: none; } .projects_holder.hover_text.no_space:not(.portfolio_full_image) > .mix{ float: left; } .projects_holder .mix .image{ position: relative; display: block; overflow: hidden; width: 100%; -moz-transform: translateZ(0px); -webkit-transform: translateZ(0px); } .projects_holder article .image img { position: relative; display: block; width: 100%; z-index: 100; } .projects_holder article .image img, .portfolio_slider .portfolio_slides li.item img { -webkit-transform: scale(1); -moz-transform: scale(1); -ms-transform: scale(1); -o-transform: scale(1); transform: scale(1); -webkit-transition: -webkit-transform 0.3s ease-in-out; -moz-transition: -moz-transform 0.3s ease-in-out; -ms-transition: -ms-transform 0.3s ease-in-out; -o-transition: -o-transform 0.3s ease-in-out; transition: transform 0.3s ease-in-out; } .projects_holder.hover_text.no_space article .image img{ margin:0 1px; } .projects_holder article .image_holder:hover .image img, .portfolio_slider .portfolio_slides li.item:hover img { -webkit-transform: scale(1.1); -moz-transform: scale(1.1); -ms-transform: scale(1.1); -o-transform: scale(1.1); transform: scale(1.1); } .projects_holder article .image_holder, .projects_holder article .portfolio_description{ display: block; position: relative; } .projects_holder article .portfolio_description{ padding:20px 0 22px; text-align:center; background-color:#fff; border-style:none; border-top:none !important; border-width:1px; border-color: #fefefe; } .projects_holder article .portfolio_description.text_align_left { text-align: left; } .projects_holder article .portfolio_description.text_align_center { text-align: center; } .projects_holder article .portfolio_description.text_align_right { text-align: right; } .standard_no_space.projects_holder article .portfolio_description{ margin: 0 -1px 0 0; } .projects_holder article .portfolio_description .portfolio_title { display: block; margin:0 0 7px 0; } .portfolio_slider .image_holder .separator.small{ margin: 10px auto; background-color: #fff; } .projects_holder article .hover_feature_holder_title .separator.small, .projects_masonry_holder article .hover_feature_holder_title .separator.small{ background-color: #fff; margin-top: 10px; margin-bottom: 10px; } .projects_holder article .portfolio_description .separator.small{ margin-top: 10px; margin-bottom: 10px; } .wpb_column>.wpb_wrapper .portfolio_slider .image_holder .separator.small { background-color: #fff; } .portfolio_slider .image_holder .separator.small.transparent{ background-color: transparent !important; } .projects_holder.hover_text article .hover_feature_holder_title .separator{ background-color: #fff; } .projects_holder.hover_text article .hover_feature_holder_title .portfolio_title a, .projects_holder.hover_text article span.text_holder span.text_inner .hover_feature_holder_title .project_category{ color: #fff; } .projects_holder.hover_text article span.text_holder span.text_inner .hover_feature_holder_title .project_category{ font-weight:500; } .projects_holder.hover_text article .hover_feature_holder_title .portfolio_title{ margin:0 0 7px; } .projects_holder article .portfolio_description .project_category, .projects_holder.hover_text article .project_category { line-height: 22px; display: block; font-size: 13px; font-weight:500; } .portfolio_single .portfolio_like{ position: relative; display: inline-block; cursor: pointer; padding: 0px; } .portfolio_single .dots{ padding: 0 7px 0 4px; } .portfolio_single .dots i{ font-size: 3px; vertical-align: middle; } .portfolio_single .portfolio_like a{ display: block; font-size: 13px; line-height: 13px; text-align: center; } .portfolio_single .portfolio_like span{ line-height: 19px; } .portfolio_slider .portfolio_like a:hover i, .portfolio_slider .portfolio_like span{ color: #e0e0e0; } .projects_holder article .portfolio_like a, .projects_holder article .portfolio_like:hover a { color: #fff; } .projects_holder article span.text_holder { background-color: #000; background-color: rgba(21, 21, 21, 0.78); bottom: 0; display: inline-block; height: 100%; left: 0; opacity: 0; position: absolute; transition: opacity 0.4s ease-in-out; -webkit-transition: opacity 0.4s ease-in-out; -moz-transition: opacity 0.4s ease-in-out; -o-transition: opacity 0.4s ease-in-out; -ms-transition: opacity 0.4s ease-in-out; visibility: visible; overflow: hidden; width: 100%; z-index: 200; } .touch .projects_holder article span.text_holder{ display: none !important; height: 0 !important; width: 0 !important; opacity: 0 !important; visibility: hidden !important; } .projects_holder article:hover span.text_holder{ height:100% !important; } .projects_holder article .image_holder:hover span.text_holder{ opacity: 1; filter: alpha(opacity=100); } .projects_holder.hover_text.with_mask article .image_holder:hover .image_hover{ opacity: 0; filter: alpha(opacity=0); } .projects_holder article span.text_holder span.text_outer{ display: table; text-align: center; vertical-align: middle; width: 100%; height: 100%; overflow:hidden; } .projects_holder article span.text_holder span span.text_inner{ display: table-cell; text-align: center; vertical-align: middle; width: 100%; height: 100%; margin: 0; padding: 0; } .projects_holder article span.text_holder span span.text_inner .project_category{ color: #A6A6A6; display: block; font-size: 13px; line-height: 22px; } .projects_holder article .feature_holder, .projects_holder article .feature_holder .feature_holder_icons{ display: inline-block; } .projects_holder.hover_text article .feature_holder{ width: 100%; } .projects_holder.hover_text article .feature_holder .feature_holder_icons{ margin:20px 0 0 0; } .portfolio_slider, .portfolio_slides .image_holder{ position: relative; display: block; -webkit-backface-visibility: hidden; } .portfolio_slides .image_pixel_hover{ position: absolute; height: 100%; width: 100%; display: block; background-color: transparent; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; z-index: 100; } .touch .portfolio_slides .image_pixel_hover{ display: none !important; } .portfolio_slides li:hover .image_pixel_hover{ background-color: #000; background-color: rgba(21, 21, 21, 0.78); } .portfolio_slides .image_holder .image { position: relative; display: block; overflow: hidden; width: 100%; -webkit-transition: -webkit-transform 0.4s; -moz-transition: -moz-transform 0.4s; transition: transform 0.4s; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; } .portfolio_slides .hover_feature_holder{ position: absolute; display: block; top: 0; left: 0; width: 100%; height: 100%; z-index: 101; } .touch .portfolio_slides .hover_feature_holder{ display: none !important; } .portfolio_slides .hover_feature_holder_icons{ position: relative; opacity: 0; text-align: center; display: inline-block; width: 100%; margin: 0 0 30px; -webkit-transition: opacity .4s ease-in-out 0.1s; -moz-transition: opacity .4s ease-in-out 0.1s; -o-transition: opacity .4s ease-in-out 0.1s; -ms-transition: opacity .4s ease-in-out 0.1s; transition: opacity .4s ease-in-out 0.1s; -webkit-transform: translateZ(0px); -moz-transform: translateZ(0px); display: none; } .portfolio_slides li:hover .hover_feature_holder_icons { opacity: 1; } .portfolio_slides .hover_feature_holder_icons_inner { display: inline-block; position: relative; } .portfolio_slides .hover_feature_holder_outer { position: relative; opacity: 1 !important; top: 0; height: 100%; display: table; width: 100%; } .portfolio_slides .hover_feature_holder_inner { height: 100%; width: 100%; top: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -o-box-sizing: border-box; box-sizing: border-box; opacity: 0; display: table-cell; vertical-align: middle; padding: 0 5%; text-align: center; color: #fff; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; } .portfolio_slides .hover_feature_holder_inner .portfolio_title { text-transform: uppercase; letter-spacing: 1px; } .portfolio_slides .hover_feature_holder_inner .portfolio_title a { color: #fff; } .portfolio_slides .hover_feature_holder_inner .qbutton { margin-top: 24px; margin-left: 5px; margin-right: 5px; } .portfolio_slides .hover_feature_holder_inner .qbutton:hover { border-color: #1abc9c; } .portfolio_slides li:hover .hover_feature_holder_inner{ opacity: 1; } .projects_holder.hover_text article .image_holder{ overflow: hidden; } .projects_holder.hover_text.no_space article .image_holder{ margin: 0 -1px; } .projects_holder article a.lightbox, .projects_holder article a.preview, .projects_holder article .portfolio_like, .portfolio_slider a.lightbox, .portfolio_slider a.preview, .portfolio_slider .portfolio_like{ position: relative; display: inline-block; margin:0 0 5px 0; -webkit-backface-visibility: hidden; } .projects_holder article a.lightbox, .portfolio_slider a.lightbox{ margin: 0 10px 0 0; } .projects_holder article .portfolio_like, .portfolio_slider .portfolio_like{ margin: 0 0 0 10px; } .projects_holder article .portfolio_like i, .portfolio_slider .portfolio_like i{ line-height: 20px; margin: 4px 0 0 0; } .portfolio_like .qode-like-count span{ display:none; } .projects_holder article .portfolio_like a:hover, .portfolio_slider .portfolio_like a:hover{ /*opacity: 0.7;*/ /*filter: alpha(opacity=70);*/ } .projects_holder article .portfolio_like .qode-like-count, .portfolio_slider article .portfolio_like .qode-like-count{ font-size: 13px; line-height: 13px; color: #fff; } .projects_holder .filler { display: inline-block; height: 0px; } .projects_holder.v6 .mix, .projects_holder.v6.hover_text .mix{ width: 15.7%; margin: 0 0 1.2%; } .projects_holder.v6.hover_text .mix{ margin: 0 0 1.7%; } .projects_holder.v6 .filler, .projects_holder.v6.hover_text .filler{ width: 15.7%; } .projects_holder.v6.standard_no_space .mix, .projects_holder.v6.hover_text.no_space .mix{ width: 16.66%; margin: 0; } .projects_holder.v6.standard_no_space .mix{ margin: 0 0 0%; } .projects_holder.v6.standard_no_space .filler, .projects_holder.v6.hover_text.no_space .filler{ width: 16.66%; } .safari_browser .projects_holder.v6.standard_no_space .mix, .safari_browser .projects_holder.v6.hover_text.no_space .mix{ width: 16.6%; } .safari_browser .projects_holder.v6.standard_no_space .filler, .safari_browser .projects_holder.v6.hover_text.no_space .filler{ width: 16.6%; } .projects_holder.v5 .mix, .projects_holder.v5.hover_text .mix{ width: 18%; margin: 0 0 2.9%; } .projects_holder.v5.hover_text .mix{ margin: 0 0 2%; } .projects_holder.v5 .filler, .projects_holder.v5.hover_text .filler{ width: 18.5%; } .projects_holder.v5.standard_no_space .mix, .projects_holder.v5.hover_text.no_space .mix{ width: 19.99%; margin: 0; } .projects_holder.v5.standard_no_space .mix{ margin: 0 0 0%; } .projects_holder.v5.standard_no_space .filler, .projects_holder.v5.hover_text.no_space .filler{ width: 19.99%; } .safari_browser .projects_holder.v5.standard_no_space .mix, .safari_browser .projects_holder.v5.hover_text.no_space .mix{ width: 19.93%; } .safari_browser .projects_holder.v5.standard_no_space .filler, .safari_browser .projects_holder.v5.hover_text.no_space .filler{ width: 19.93%; } .projects_holder.v4 .mix, .projects_holder.v4.hover_text .mix{ width: 23.5%; margin: 0 0 2.5%; } .projects_holder.v4.hover_text .mix{ margin: 0 0 2.2%; } .projects_holder.v4 .filler, .projects_holder.v4.hover_text .filler{ width: 23.5%; } .projects_holder.v4.standard_no_space .mix, .projects_holder.v4.hover_text.no_space .mix{ width: 24.99%; margin: 0; } .projects_holder.v4.standard_no_space .mix{ margin: 0 0 0; } .projects_holder.v4.standard_no_space .filler, .projects_holder.v4.hover_text.no_space .filler{ width: 24.99%; } .projects_holder.v3 .mix, .projects_holder.v3.hover_text .mix{ width: 32%; margin: 0 0 2.4%; } .projects_holder.v3.hover_text .mix{ margin: 0 0 2.2%; } .projects_holder.v3 .filler, .projects_holder.v3.hover_text .filler{ width: 32%; } .projects_holder.v3.standard_no_space .mix, .projects_holder.v3.hover_text.no_space .mix{ width: 33.32%; margin: 0; } .projects_holder.v3.standard_no_space .mix{ margin: 0 0 0%; } .projects_holder.v3.standard_no_space .filler, .projects_holder.v3.hover_text.no_space .filler{ width: 33.32%; } .safari_browser .projects_holder.v3.standard_no_space .mix, .safari_browser .projects_holder.v3.hover_text.no_space .mix{ width: 33.3%; } .safari_browser .projects_holder.v3.standard_no_space .filler, .safari_browser .projects_holder.v3.hover_text.no_space .filler{ width: 33.3%; } .projects_holder.v2 .mix, .projects_holder.v2.hover_text .mix{ width: 49%; margin: 0 0 2.4%; } .projects_holder.v2.hover_text .mix{ margin: 0 0 2.1%; } .projects_holder.v2 .filler, .projects_holder.v2.hover_text .filler{ width: 49%; } .projects_holder.v2.standard_no_space .mix, .projects_holder.v2.hover_text.no_space .mix{ width: 49.99%; margin: 0; } .projects_holder.v2.standard_no_space .mix{ margin: 0 0 0%; } .projects_holder.v2.standard_no_space .filler, .projects_holder.v2.hover_text.no_space .filler{ width: 49.99%; } .portfolio_paging, .portfolio_paging_loading { text-align: center; margin: 40px 0 0; } .portfolio_paging_loading { display: none; } .portfolio_with_space .portfolio_paging, .portfolio_with_space .portfolio_paging_loading { margin: 15px 0 0; } .filter_outer{ display: table; width: 100%; position: relative; height: 37px; margin: -30px 0 40px; text-align:center; } .vertical_menu_enabled .full_width .filter_outer{ margin: 0 0 40px; } .filter_holder { display:table-cell; vertical-align: middle; } .filter_holder ul { display: inline-block; list-style: none; } .filter_holder ul li { cursor: pointer; display: block; margin: 0; float:left; text-align: center; } .filter_holder ul li span { display: inline-block; padding: 0 22px; position: relative; letter-spacing:1px; text-transform: uppercase; font-weight: 600; } .filter_holder ul li.active span{ color:#1abc9c !important; } .filter_holder ul li:hover span{ color:#1abc9c !important; } /* Portfolio Masonry styles ========================================================================== */ .projects_masonry_holder{ opacity: 0; } .projects_masonry_holder .portfolio_masonry_item, .projects_masonry_holder .portfolio_masonry_item.large_height{ width: 33.33%; } .projects_masonry_holder .portfolio_masonry_item.large_width, .projects_masonry_holder .portfolio_masonry_item.large_width_height{ width: 66.66%; } .full_width .projects_masonry_holder .portfolio_masonry_item, .full_width .projects_masonry_holder .portfolio_masonry_item.large_height{ width: 19.96%; } .full_width .projects_masonry_holder .portfolio_masonry_item.large_width, .full_width .projects_masonry_holder .portfolio_masonry_item.large_width_height{ width: 39.92%; } .full_width .projects_masonry_holder.gs4 .portfolio_masonry_item, .full_width .projects_masonry_holder.gs4 .portfolio_masonry_item.large_height, .projects_masonry_holder.gs4 .portfolio_masonry_item, .projects_masonry_holder.gs4 .portfolio_masonry_item.large_height { width: 25%; } .full_width .projects_masonry_holder.gs4 .portfolio_masonry_item.large_width, .full_width .projects_masonry_holder.gs4 .portfolio_masonry_item.large_width_height, .projects_masonry_holder.gs4 .portfolio_masonry_item.large_width, .projects_masonry_holder.gs4 .portfolio_masonry_item.large_width_height { width: 50%; } .projects_masonry_holder:after, .projects_masonry_holder .portfolio_masonry_item:after { clear: both; content: ""; display: block; height: 0; visibility: hidden; } .projects_masonry_holder .image_holder img{ vertical-align: top; width: 100%; height: auto; } .projects_masonry_holder .image_holder{ margin: 0px -1px 0px 0px; } .projects_masonry_holder .text_holder{ position: absolute; top: 0; left: 0; width: 100.2%; /* beacuse there is one pixel o right side that is not covered with hover shader */ height: 100%; background-color: rgba(0,0,0,0.8); text-align: center; transition: opacity 0.4s ease-in-out; -webkit-transition: opacity 0.4s ease-in-out; -moz-transition: opacity 0.4s ease-in-out; -o-transition: opacity 0.4s ease-in-out; -ms-transition: opacity 0.4s ease-in-out; visibility: visible; overflow: hidden; z-index: 200; opacity: 0; filter: alpha(opacity=0); } .projects_masonry_holder .text_holder .text_outer{ display: table; text-align: center; vertical-align: middle; width: 100%; height: 100%; overflow: hidden; } .projects_masonry_holder .text_holder .text_inner{ display: table-cell; text-align: center; vertical-align: middle; width: 100%; height: 100%; margin: 0; padding: 0; } .projects_masonry_holder article.portfolio_masonry_item:hover .text_holder{ opacity: 1; filter: alpha(opacity=100); } .projects_masonry_holder .portfolio_title { margin: 0 0 7px; } .projects_masonry_holder .portfolio_title a{ color: #fff; } .projects_masonry_holder .project_category, .masonry_with_space_only_image .project_category { font-weight: 500; } .projects_masonry_holder .separator, .masonry_with_space_only_image .separator{ background-color: #fff; } .projects_masonry_holder .feature_holder_icons { margin: 20px 0 0 0; display: inline-block; } .projects_masonry_holder .feature_holder { width: 100%; display: inline-block; } .projects_masonry_holder a.lightbox { margin: 0 10px 0 0; } .projects_masonry_holder .portfolio_like { margin: 0 0 0 10px; } .projects_masonry_holder .portfolio_like a, .projects_masonry_holder .portfolio_like:hover a { color: #fff; } .masonry_with_space .projects_holder{ position: relative; opacity: 0; } .masonry_with_space .projects_holder .mix{ display: block; padding: 0px 7px; margin: 0px 0px 14px 0px !important; -webkit-transition: none; -moz-transition: none; -o-transition: none; transition: none; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; visibility: visible; } .masonry_with_space .projects_holder.v6 .mix{ width: 16.66%; } .masonry_with_space .projects_holder.v5 .mix{ width: 20%; } .masonry_with_space .projects_holder.v4 .mix{ width: 25%; } .masonry_with_space .projects_holder.v3 .mix{ width: 33.33%; } .masonry_with_space .projects_holder.v2 .mix{ width: 49.99%; } /*----------------------Portfolio "Fade - one by one" loading type-------------------------------*/ .projects_holder_outer:not(.masonry_with_space) .projects_holder.portfolio_one_by_one article{ opacity: 0 !important; } .projects_holder_outer:not(.masonry_with_space) .projects_holder.portfolio_one_by_one article.show{ opacity: 1 !important; } .projects_holder_outer.masonry_with_space .projects_holder.portfolio_one_by_one article, .projects_masonry_holder.portfolio_one_by_one article{ opacity: 0; } .projects_holder_outer.masonry_with_space .projects_holder.portfolio_one_by_one article.show, .projects_masonry_holder.portfolio_one_by_one article.show{ opacity: 1; } /*---------------------Portfolio "Slide from top - diagonal" loading type-------------------------*/ .projects_holder.slide_from_top article{ overflow:hidden; } .projects_holder.slide_from_top article .image_holder, .projects_holder.slide_from_top article .portfolio_description{ opacity: 0 !important; -webkit-transform: translateY(-70%); transform: translateY(-70%); -moz-transition: -moz-transform 0.4s cubic-bezier(.4,0,.2,1), opacity 0.4s cubic-bezier(.4,0,.2,1); -webkit-transition: -webkit-transform 0.4s cubic-bezier(.4,0,.2,1), opacity 0.4s cubic-bezier(.4,0,.2,1); transition: transform 0.4s cubic-bezier(.4,0,.2,1), opacity 0.4s cubic-bezier(.4,0,.2,1); } .projects_holder.slide_from_top article.show .image_holder, .projects_holder.slide_from_top article.show .portfolio_description{ opacity: 1 !important; -webkit-transform: translateY(0); transform: translateY(0); } /*---------------------Portfolio "Fade - diagonal" loading type-------------------------*/ .projects_holder.diagonal_fade article{ opacity: 0 !important; -moz-transition: opacity 0.4s ease-in-out, -moz-transform 0.4s ease-in-out; -webkit-transition: opacity 0.4s ease-in-out, -webkit-transform 0.4s ease-in-out; transition:opacity 0.4s ease-in-out, transform 0.4s ease-in-out; -webkit-transform: scale(0.8); -moz-transform: scale(0.8); transform: scale(0.8); } .projects_holder.diagonal_fade article.show{ opacity: 1 !important; -webkit-transform: scale(1); transform: scale(1); } /*---------------------Portfolio "Slide from left - random" loading type-------------------------*/ .projects_holder.slide_from_left article{ overflow:hidden; } .projects_holder.slide_from_left article .image_holder, .projects_holder.slide_from_left article .portfolio_description{ opacity: 0 !important; -webkit-transform: translateX(-100%); transform: translateX(-100%); -moz-transition: -moz-transform 0.3s cubic-bezier(.4,0,.2,1), opacity 0.3s cubic-bezier(.4,0,.2,1); -webkit-transition: -webkit-transform 0.3s cubic-bezier(.4,0,.2,1), opacity 0.3s cubic-bezier(.4,0,.2,1); transition: transform 0.3s cubic-bezier(.4,0,.2,1), opacity 0.3s cubic-bezier(.4,0,.2,1); } .projects_holder.slide_from_left article.show .image_holder, .projects_holder.slide_from_left article.show .portfolio_description{ opacity: 1 !important; -webkit-transform: translateX(0); transform: translateX(0); } /*---------------------Portfolio "Fade from bottom" loading type-------------------------*/ .projects_holder.portfolio_fade_from_bottom article, .projects_masonry_holder.portfolio_fade_from_bottom article { opacity: 0; -ms-transform: translateY(150px); -webkit-transform: translateY(150px); transform: translateY(150px); -ms-transition: opacity 0.8s ease, -ms-transform 0.8s ease !important; -webkit-transition: opacity 0.8s ease, -webkit-transform 0.8s ease !important; transition: opacity 0.8s ease, transform 0.8s ease !important; } .projects_holder.portfolio_fade_from_bottom article.show, .projects_masonry_holder.portfolio_fade_from_bottom article.show { opacity: 1; margin-top: 0px; -ms-transform: translateY(0px); -webkit-transform: translateY(0px); transform: translateY(0px); } /* ========================================================================== #Portfolio Masonry With Space Without Description ========================================================================== */ .masonry_with_space_only_image .hover_feature_holder_title_inner . portfolio_title { margin-bottom: 7px; } .masonry_with_space_only_image .hover_feature_holder_title_inner .portfolio_title, .masonry_with_space_only_image .hover_feature_holder_title_inner .portfolio_title a, .masonry_with_space_only_image .projects_holder article span.text_holder span span.text_inner .project_category { color: #fff; } .projects_holder.standard article .item_holder.image_text_zoom_hover .project_category { margin-bottom: 10px; } .masonry_with_space_only_image .feature_holder { margin-top: 30px; } /* ========================================================================== #End of Portfolio Masonry With Space Without Description ========================================================================== */ /* ========================================================================== #Portfolio Hover effects styles ========================================================================== */ .portfolio_main_holder .item_holder { position: relative; } .projects_holder article a.portfolio_link_class, .projects_masonry_holder article a.portfolio_link_class { position: absolute; width: 100%; height: 100%; } .portfolio_main_holder .item_holder .text_holder { position: absolute; } .portfolio_main_holder .project_category { margin: 0; display: block; line-height: 1; font-size: 12px; } .portfolio_main_holder .item_holder .text_holder_outer { display: table; width:100%; height: 100%; } .portfolio_main_holder .item_holder .text_holder_inner{ display: table-cell; vertical-align: middle; text-align:center; } .portfolio_main_holder .item_holder .portfolio_shader { position: absolute; width:100%; height: 100%; background-color: rgba(21,21,21,0.78); } .portfolio_main_holder .item_holder .icons_holder{ font-family: "Raleway",sans-serif; /* this css is here to overwrite other font-family (from body) which can make problem in icon height */ } .portfolio_main_holder .item_holder .icons_holder a { text-align: center; } .portfolio_main_holder .item_holder .portfolio_title { line-height:1.25em; } .projects_holder.standard article .project_category, .projects_holder.standard_no_space article .project_category, .portfolio_slider_holder.standard li .project_category{ margin:10px 0 0 0; } .projects_holder article a.portfolio_link_class, .projects_masonry_holder article a.portfolio_link_class { z-index: 5; left: 0; } .portfolio_main_holder article .icons_holder a.portfolio_lightbox:before, .portfolio_slides .icons_holder a.portfolio_lightbox:before{ font-family: 'FontAwesome'; content: "\f067"; line-height: inherit; } .portfolio_main_holder article .icons_holder a.qode-like:before, .portfolio_slides .icons_holder a.qode-like:before{ font-family: 'FontAwesome'; content: "\f08a"; line-height: inherit; } .portfolio_main_holder article .icons_holder a.qode-like.liked:before, .portfolio_slides .icons_holder a.qode-like.liked:before{ font-family: "FontAwesome"; content: "\f004"; line-height: inherit; } .portfolio_main_holder article .icons_holder a.preview:before, .portfolio_slides .icons_holder a.preview:before { content: "\f0c1"; font-family: "FontAwesome"; line-height: inherit; } .portfolio_main_holder .item_holder .portfolio_title a, .portfolio_main_holder .item_holder .project_category { color: #fff; } .portfolio_main_holder .item_holder .portfolio_title { margin-bottom: 15px; } /* #Subtle vertical hover ========================================================================== */ .projects_holder article .item_holder.subtle_vertical_hover a.portfolio_link_class, .projects_masonry_holder article .item_holder.subtle_vertical_hover a.portfolio_link_class { z-index: 5 } .portfolio_main_holder .item_holder.subtle_vertical_hover .image_holder { z-index: 2 } .portfolio_main_holder .item_holder.subtle_vertical_hover .text_holder { font-size: 14px; width: 100%; position: absolute; left: 0; height: 100%; background-color: transparent; top: 0; text-align: center; box-sizing: border-box; z-index: 4; opacity: 0; } .portfolio_main_holder article .item_holder.subtle_vertical_hover:hover .text_holder, .portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .text_holder { opacity: 1 } .portfolio_main_holder .item_holder.subtle_vertical_hover .text_holder_inner { padding: 5px; } .portfolio_main_holder .item_holder.subtle_vertical_hover .portfolio_title { text-transform: uppercase; opacity: 0; padding: 0 20px; -ms-transform: translateY(0px); -moz-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); -webkit-transform: translateY(0px); transition: all 0.3s ease-out; -webkit-transition: all 0.3s ease-out; } .portfolio_main_holder article:hover .item_holder.subtle_vertical_hover .portfolio_title, .portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .portfolio_title { opacity: 1; text-shadow: none; -ms-transform: translateY(4px); -moz-transform: translateY(4px); -o-transform: translateY(4px); transform: translateY(4px); -webkit-transform: translateY(4px); transition: all 0.3s ease-out; -webkit-transition: all 0.3s ease-out; } .portfolio_main_holder .item_holder.subtle_vertical_hover .text_holder .separator { display: inline-block; background-color: #fff; margin-top: 20px; } .portfolio_main_holder .item_holder.subtle_vertical_hover .project_category { opacity: 0; -ms-transform: translateY(4px); -moz-transform: translateY(4px); -o-transform: translateY(4px); transform: translateY(4px); -webkit-transform: translateY(4px); transition: all 0.4s ease-out; -webkit-transition: all 0.4s ease-out; margin-bottom: 10px; } .portfolio_main_holder article:hover .item_holder.subtle_vertical_hover .project_category, .portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .project_category { opacity: 1; text-shadow: none; -ms-transform: translateY(0px); -moz-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); -webkit-transform: translateY(0px); } .portfolio_main_holder .item_holder.subtle_vertical_hover .icons_holder { -ms-transform: translateY(4px); -moz-transform: translateY(4px); -o-transform: translateY(4px); transform: translateY(4px); -webkit-transform: translateY(4px); transition: all 0.4s ease-out; -webkit-transition: all 0.4s ease-out; } .portfolio_main_holder article .item_holder.subtle_vertical_hover:hover .icons_holder, .portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .icons_holder { -ms-transform: translateY(0); -moz-transform: translateY(0); -o-transform: translateY(0); transform: translateY(0); -webkit-transform: translateY(0); } .portfolio_main_holder .item_holder.subtle_vertical_hover .icons_holder a { display: inline-block; width: 40px; height: 40px; line-height: 40px; background-color: #1abc9c; border-radius: 100px; margin: 0 3px; color: #fff; transition: 0.2s ease-out; -webkit-transition: 0.2s ease-out; } .portfolio_main_holder .item_holder.subtle_vertical_hover .portfolio_shader { z-index: 3; -webkit-transition: opacity 0.3s cubic-bezier(.785, .135, .15, .86); transition: opacity 0.3s cubic-bezier(.785, .135, .15, .86); opacity: 0; } .portfolio_main_holder article .item_holder.subtle_vertical_hover:hover .portfolio_shader, .portfolio_slider li.item:hover .item_holder.subtle_vertical_hover .portfolio_shader { opacity: 1 } /* #End of Subtle vertical hover ========================================================================== */ /* #Image subtle rotate zoom hover ========================================================================== */ .portfolio_main_holder article .item_holder.image_subtle_rotate_zoom_hover a.portfolio_link_class { z-index: 5; } .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .image_holder { z-index: 2; overflow: hidden; } .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .text_holder { padding: 30px; font-size: 14px; width: 100%; position: absolute; left: 0; height: 100%; background-color: transparent; top: 0; box-sizing: border-box; z-index: 4; opacity: 1; } .portfolio_with_hover_text .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .separator { background-color: #fff; opacity: 0; -webkit-transition: opacity 0.4s ease-out; -moz-transition: opacity 0.4s ease-out; -ms-transition: opacity 0.4s ease-out; -o-transition: opacity 0.4s ease-out; transition: opacity 0.4s ease-out; } .portfolio_with_hover_text .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover:hover .separator { opacity: 1; } .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .portfolio_title { font-weight: 600; font-size: 15px; text-transform: uppercase; opacity: 0; letter-spacing: 2px; -ms-transform: translateY(-3px); -moz-transform: translateY(-3px); -o-transform: translateY(-3px); transform: translateY(-3px); -webkit-transform: translateY(-3px); transition: all 0.4s ease-out; -webkit-transition: all 0.4s ease-out; } .portfolio_main_holder article:hover .item_holder.image_subtle_rotate_zoom_hover .portfolio_title, .portfolio_slider li.item:hover .item_holder.image_subtle_rotate_zoom_hover .portfolio_title { opacity: 1; text-shadow: none; -ms-transform: translateY(0px); -moz-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); -webkit-transform: translateY(0px); } .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .project_category { opacity: 0; text-shadow: 0px 0px 10px #fff; -ms-transform: translateY(3px); -moz-transform: translateY(3px); -o-transform: translateY(3px); transform: translateY(3px); -webkit-transform: translateY(3px); transition: all 0.4s ease-out; -webkit-transition: all 0.4s ease-out; } .portfolio_main_holder article:hover .item_holder.image_subtle_rotate_zoom_hover .project_category { opacity: 1; text-shadow: none; -ms-transform: translateY(0px); -moz-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); -webkit-transform: translateY(0px); } .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .portfolio_shader { z-index: 3; -webkit-transition: opacity 0.3s cubic-bezier(.785, .135, .15, .86); transition: opacity 0.3s cubic-bezier(.785, .135, .15, .86); opacity: 0; } .portfolio_main_holder article .item_holder.image_subtle_rotate_zoom_hover:hover .portfolio_shader, .portfolio_slider li.item:hover .item_holder.image_subtle_rotate_zoom_hover .portfolio_shader { opacity: 1; } .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .icons_holder { -ms-transform: translateY(3px); -moz-transform: translateY(3px); -o-transform: translateY(3px); transform: translateY(3px); -webkit-transform: translateY(3px); transition: transform 0.4s ease-out; -webkit-transition: transform 0.4s ease-out; opacity: 0; } .portfolio_main_holder article .item_holder.image_subtle_rotate_zoom_hover:hover .icons_holder, .portfolio_slider li.item:hover .item_holder.image_subtle_rotate_zoom_hover .icons_holder { -ms-transform: translateY(0); -moz-transform: translateY(0); -o-transform: translateY(0); transform: translateY(0); -webkit-transform: translateY(0); opacity: 1; } .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .icons_holder a { display: inline-block; background-color: transparent; border: 1px solid #fff; width: 40px; height: 40px; line-height: 40px; color: #fff; border-radius: 100px; margin: 0 3px; transition: 0.2s ease-out; -webkit-transition: 0.2s ease-out; } .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .icons_holder a:hover { background-color: #1abc9c; color: #fff; border-color: #1abc9c; } .portfolio_main_holder .item_holder.image_subtle_rotate_zoom_hover .image_holder .image img { -webkit-transition: -webkit-transform .7s; transition: transform .7s; } .portfolio_main_holder article .item_holder.image_subtle_rotate_zoom_hover:hover .image_holder .image img, .portfolio_slider li.item:hover .item_holder.image_subtle_rotate_zoom_hover .image_holder .image img { -webkit-transform: rotate(-9deg) scale(1.15); -ms-transform: rotate(-9deg) scale(1.15); -moz-transform: rotate(-9deg) scale(1.15); -o-transform: rotate(-9deg) scale(1.15); transform: rotate(-9deg) scale(1.15); -webkit-transition: -webkit-transform .7s; transition: transform .7s; backface-visibility: hidden; -webkit-backface-visibility: hidden; } /* #End of image subtle rotate zoom hover ========================================================================== */ /* #Image text zoom hover ========================================================================== */ .portfolio_main_holder article .item_holder.image_text_zoom_hover a.portfolio_link_class { z-index: 5; } .portfolio_main_holder .item_holder.image_text_zoom_hover .image_holder { z-index: 2; overflow: hidden; } .portfolio_main_holder .item_holder.image_text_zoom_hover .text_holder { padding: 30px; font-size: 14px; width: 100%; height: 100%; position: absolute; left: 0; background-color: transparent; top: 0; text-align: center; box-sizing: border-box; opacity: 0; -webkit-transition: 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); transition: 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); backface-visibility: hidden; -webkit-backface-visibility: hidden; -webkit-transform: scale(0.8); -ms-transform: scale(0.8); -moz-transform: scale(0.8); -o-transform: scale(0.8); transform: scale(0.8); z-index: 4; } .portfolio_main_holder article .item_holder.image_text_zoom_hover:hover .text_holder, .portfolio_slider li.item:hover .item_holder.image_text_zoom_hover .text_holder { opacity: 1; -webkit-transform: scale(1); -ms-transform: scale(1); -moz-transform: scale(1); -o-transform: scale(1); transform: scale(1); } .portfolio_main_holder .item_holder.image_text_zoom_hover .text_holder_outer { display: table; width: 100%; height: 100%; } .portfolio_main_holder .item_holder.image_text_zoom_hover .text_holder_inner { display: table-cell; vertical-align: middle; text-align: center; } .portfolio_with_hover_text .portfolio_main_holder .item_holder.image_text_zoom_hover .separator { background-color: #fff; } .portfolio_main_holder .project_category, .projects_masonry_holder article .project_category { margin-bottom: 10px; } .portfolio_main_holder .item_holder.image_text_zoom_hover .icons_holder a { display: inline-block; width: 40px; height: 40px; line-height: 40px; background-color: #1abc9c; border-radius: 50%; margin: 0 2px; color: #fff; -ms-transform: translateY(0); -moz-transform: translateY(0); -o-transform: translateY(0); transform: translateY(0); -webkit-transform: translateY(0); transition: background-color 0.2s, transform 0.2s; -webkit-transition: background-color 0.2s, -webkit-transform 0.2s; } .portfolio_main_holder .item_holder.image_text_zoom_hover .icons_holder a:hover { -ms-transform: translateY(-10%); -moz-transform: translateY(-10%); -o-transform: translateY(-10%); transform: translateY(-10%); -webkit-transform: translateY(-10%); } .portfolio_main_holder .item_holder.image_text_zoom_hover .portfolio_shader { z-index: 3; -webkit-backface-visibility: hidden; backface-visibility: hidden; -webkit-transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); opacity: 0; } .portfolio_main_holder article .item_holder.image_text_zoom_hover:hover .portfolio_shader, .portfolio_slider li.item:hover .item_holder.image_text_zoom_hover .portfolio_shader { opacity: 1 } .portfolio_main_holder .item_holder.image_text_zoom_hover .image_holder .image { -webkit-transition: 0.5s cubic-bezier(0.19, 1, 0.22, 1); transition: 0.5s cubic-bezier(0.19, 1, 0.22, 1); backface-visibility: hidden; -webkit-backface-visibility: hidden; display: inline-block; } .portfolio_main_holder article .item_holder.image_text_zoom_hover:hover .image_holder .image, .portfolio_slider li.item:hover .item_holder.image_text_zoom_hover .image_holder .image { -webkit-transform: scale(1.3); -ms-transform: scale(1.3); -moz-transform: scale(1.3); -o-transform: scale(1.3); transform: scale(1.3); } /* #End of image text zoom hover ========================================================================== */ /* #Thin plus only hover ========================================================================== */ .portfolio_main_holder.standard .item_holder.thin_plus_only { overflow: hidden; } .portfolio_main_holder .item_holder.thin_plus_only .thin_plus_only_icon { font-weight: 100; font-family: Raleway; font-size: 100px; -webkit-transition: all 0.5s 0.3s; transition: all 0.5s 0.3s; display: block; color: #fff; } .portfolio_main_holder .item_holder.thin_plus_only .text_holder { width: 100%; height: 100%; left: 0; margin: 0; top: 0; box-sizing: border-box; z-index: 5; -ms-transform: translate(20%, 20%); -moz-transform: translate(20%, 20%); -o-transform: translate(20%, 20%); transform: translate(20%, 20%); -webkit-transform: translate(20%, 20%); -webkit-transition: all 0.5s 0.3s; transition: all 0.5s 0.3s; opacity: 0; font-size: 0; padding: 10%; background-color: transparent; } .portfolio_main_holder article .item_holder.thin_plus_only:hover .text_holder, .portfolio_slider li:hover .item_holder.thin_plus_only .text_holder { -ms-transform: translate(0, 0); -moz-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); -webkit-transform: translate(0, 0); -webkit-transition: all 0.2s 0.1s; transition: all 0.2s 0.1s; font-size: 150px; opacity: 1 } .portfolio_main_holder .item_holder.thin_plus_only .image_holder { z-index: 2; } .portfolio_main_holder .item_holder.thin_plus_only .portfolio_shader { z-index: 3; transition: opacity 0.5s; -webkit-transition: opacity 0.5s; opacity: 0; } .portfolio_main_holder article .item_holder.thin_plus_only:hover .portfolio_shader, .portfolio_slider li.item:hover .item_holder.thin_plus_only .portfolio_shader { opacity: 1 } /* #End of thin plus only hover ========================================================================== */ /* #Slow Zoom hover ========================================================================== */ .portfolio_main_holder .item_holder.slow_zoom .text_holder { width: 100%; font-size: 18px; left: 0; height: 100%; margin: 0; top: 0; box-sizing: border-box; z-index: 5; -webkit-transition: opacity 0.6s 0.3s; transition: opacity 0.6s 0.3s; opacity: 0; padding: 10%; background-color: transparent; } .portfolio_main_holder article .item_holder.slow_zoom:hover .text_holder { opacity: 1 } .portfolio_with_hover_text .portfolio_main_holder article .item_holder.slow_zoom .separator { background-color: #fff; } .portfolio_main_holder .item_holder.slow_zoom .image_holder img { -webkit-transform: scale(1.01); -moz-transform: scale(1.01); -o-transform: scale(1.01); -ms-transform: scale(1.01); transform: scale(1.01); -webkit-transition: all 2s cubic-bezier(0.21, 1, 0.12, 1) 0s; transition: all 2s cubic-bezier(0.23, 1, 0.12, 1) 0s; } .portfolio_main_holder article .item_holder.slow_zoom:hover .image_holder img { -webkit-transform: scale(1.1); -moz-transform: scale(1.1); -o-transform: scale(1.1); -ms-transform: scale(1.1); transform: scale(1.1); -webkit-transition: all 5s cubic-bezier(0.21, 1, 0.12, 1) 0s; transition: all 5s cubic-bezier(0.21, 1, 0.12, 1) 0s; } .portfolio_main_holder .item_holder.slow_zoom .portfolio_shader { z-index: 3; opacity: 0; -webkit-transition: all 5s cubic-bezier(0.21, 1, 0.12, 1) 0s; transition: all 5s cubic-bezier(0.21, 1, 0.12, 1) 0s; } .portfolio_main_holder article .item_holder.slow_zoom:hover .portfolio_shader, .portfolio_slider li.item:hover .item_holder.slow_zoom .portfolio_shader { opacity: 1; } .portfolio_main_holder .item_holder.slow_zoom .icons_holder { position: absolute; bottom: 0; opacity: 0; z-index: 20; -webkit-transition: opacity .3s, -webkit-transform .3s; transition: opacity .3s, transform .3s; } .portfolio_main_holder .item_holder.slow_zoom .icons_holder.left { left: 0; -webkit-transform: translate3d(-10px, -10px, 0); -ms-transform: translate3d(-10px, 10px, 0); -moz-transform: translate3d(-10px, 10px, 0); -o-transform: translate3d(-10px, 10px, 0); transform: translate3d(-10px, 10px, 0); } .portfolio_main_holder .item_holder.slow_zoom .icons_holder.right { right: 0; -webkit-transform: translate3d(10px, 10px, 0); -ms-transform: translate3d(10px, 10px, 0); -moz-transform: translate3d(10px, 10px, 0); -o-transform: translate3d(10px, 10px, 0); transform: translate3d(10px, 10px, 0); } .portfolio_main_holder .item_holder.slow_zoom .icons_holder.center { width: 100%; text-align: center; -webkit-transform: translate3d(0, 10px, 0); -ms-transform: translate3d(0, 10px, 0); -moz-transform: translate3d(0, 10px, 0); -o-transform: translate3d(0, 10px, 0); transform: translate3d(0, 10px, 0); } .portfolio_main_holder article:hover .item_holder.slow_zoom .icons_holder, .portfolio_slider li.item:hover .item_holder.slow_zoom .icons_holder { opacity: 1; display: block; -webkit-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } .portfolio_main_holder .item_holder.slow_zoom .icons_holder a { display: inline-block; width: 40px; height: 40px; line-height: 40px; text-align: center; vertical-align: middle; margin: 0; font-size: 15px; color: #fff; background: #1abc9c; transition: all .4s; -webkit-transition: all .4s; } .portfolio_main_holder .item_holder.slow_zoom .icons_holder a:hover { background: #fff; color: #000; } .portfolio_main_holder .item_holder.slow_zoom .image_holder { z-index: 2; overflow: hidden; } /* #End of soom zhover ========================================================================== */ /* #Split up hover ========================================================================== */ .portfolio_main_holder .item_holder.split_up .text_holder { width: 100%; font-size: 18px; left: 0; height: 100%; margin: 0; top: 0; box-sizing: border-box; z-index: 5; -webkit-transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); opacity: 0; padding: 10%; background-color: transparent; } .portfolio_main_holder article .item_holder.split_up:hover .text_holder { -webkit-transition: transform 0.3s ease; transition: transform 0.3s ease; opacity: 1; } .portfolio_main_holder .item_holder.split_up .portfolio_title { -ms-transform: translateY(0); -moz-transform: translateY(0); -o-transform: translateY(0); transform: translateY(0); -webkit-transform: translateY(0); transition: 0.2s; -webkit-transition: 0.2s; } .portfolio_main_holder article .item_holder.split_up:hover .portfolio_title { -ms-transform: translateY(-4px); -moz-transform: translateY(-4px); -o-transform: translateY(-4px); transform: translateY(-4px); -webkit-transform: translateY(-4px); } .portfolio_main_holder .item_holder.split_up .project_category { -ms-transform: translateY(-4px); -moz-transform: translateY(-4px); -o-transform: translateY(-4px); transform: translateY(-4px); -webkit-transform: translateY(-4px); transition: 0.2s; -webkit-transition: 0.2s; } .portfolio_main_holder article:hover .item_holder.split_up .project_category { -ms-transform: translateY(0); -moz-transform: translateY(0); -o-transform: translateY(0); transform: translateY(0); -webkit-transform: translateY(0); } .portfolio_with_hover_text .portfolio_main_holder article:hover .item_holder.split_up .separator { background-color: #fff; } .portfolio_main_holder .item_holder.split_up .image_holder { z-index: 2; } .portfolio_main_holder .item_holder.split_up .portfolio_shader, .portfolio_slider li.item .item_holder.split_up .portfolio_shader { height: 0; display: block; left: 0; opacity: 0; position: absolute; top: 50%; -webkit-transition: all 0.2s ease-out; transition: all 0.2s ease-out; width: 100%; z-index: 3; } .portfolio_main_holder article .item_holder.split_up:hover .portfolio_shader, .portfolio_slider li.item:hover .item_holder.split_up .portfolio_shader { height: 100%; top: 0; opacity: 1; } /* #End of split up hover ========================================================================== */ /* #Cursor change hover ========================================================================== */ .portfolio_main_holder .item_holder.cursor_change_hover a.portfolio_link_class { z-index: 6; cursor: url("img/cursor_plus.cur"), crosshair; cursor: url("img/cursor_plus.png") 22 22, crosshair; } .portfolio_main_holder .cursor_img { position: absolute; z-index: 1000; } .portfolio_main_holder .item_holder.cursor_change_hover .image_holder { z-index: 2 } .portfolio_main_holder .item_holder.cursor_change_hover .text_holder { padding: 30px; font-size: 14px; width: 100%; height: 100%; position: absolute; left: 0; background-color: transparent; top: 0; text-align: center; box-sizing: border-box; opacity: 0; -webkit-transition: 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); transition: 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); backface-visibility: hidden; -webkit-backface-visibility: hidden; -webkit-transform: scale(0.8); -ms-transform: scale(0.8); -moz-transform: scale(0.8); -o-transform: scale(0.8); transform: scale(0.8); z-index: 4; } .portfolio_main_holder article:hover .item_holder.cursor_change_hover .text_holder, .portfolio_slider li.item:hover .item_holder.cursor_change_hover .text_holder { opacity: 1; -webkit-transform: scale(1); -ms-transform: scale(1); -moz-transform: scale(1); -o-transform: scale(1); transform: scale(1); } .portfolio_with_hover_text .portfolio_main_holder .item_holder.cursor_change_hover .separator { background-color: #fff } .portfolio_main_holder .item_holder.cursor_change_hover .text_holder_outer { display: table; width: 100%; height: 100%; } .portfolio_main_holder .item_holder.cursor_change_hover .text_holder_inner { display: table-cell; vertical-align: middle; text-align: center; } .portfolio_main_holder .item_holder.cursor_change_hover .portfolio_shader { z-index: 3; -webkit-transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); transition: opacity 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); opacity: 0; } .portfolio_main_holder article .item_holder.cursor_change_hover:hover .portfolio_shader, .portfolio_slider li.item:hover .item_holder.cursor_change_hover .portfolio_shader { opacity: 1 } /* #End of cursor change hover ========================================================================== */ /* ========================================================================== #End of Portfolio Hover effects styles ========================================================================== */ /* ========================================================================== Tabs shortcode start styles ========================================================================== */ .q_tabs{ display: block; visibility: hidden; } .q_tabs .tabs-nav { list-style: none outside none; margin: 0; overflow: hidden; padding: 0; display: inline-block; position: relative; } .q_tabs .tabs-nav li { margin: 0; overflow: hidden; padding: 0; position: relative; display: inline-block; float: left; } .q_tabs .tabs-nav li a { height: 40px; line-height: 40px; display: block; margin: 0; padding: 0 14px; font-size: 13px; text-decoration: none; font-style: normal; color: #b4b4b4; text-transform: uppercase; letter-spacing: 1px; font-weight: 700; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; } .q_tabs .tabs-nav li.active a { color: #303030; } .q_tabs .tabs-nav li.active a:hover, .q_tabs .tabs-nav li a:hover { color: #1abc9c; } /* Horizontal tabs styles ========================================================================== */ .q_tabs.horizontal.center { text-align: center; } .q_tabs.horizontal.left { text-align: left; } .q_tabs.horizontal.right { text-align: right; } .q_tabs.horizontal .tabs-container { padding-top: 4px; text-align: left; } .q_tabs.horizontal.right .tabs-container { text-align: right; } .q_tabs.horizontal .tabs-nav li:first-child a { padding-left: 0; } /* Vertical tabs styles ========================================================================== */ .q_tabs.vertical .tabs-nav { width: 24.02957486136784%; margin: 0; } .q_tabs.vertical.right .tabs-nav { float: right; } .q_tabs.vertical.left .tabs-nav { float: left; } .q_tabs.vertical .tabs-nav li { display: block; width: 100%; } .q_tabs.vertical .tabs-nav li a { text-align: center; height: auto; line-height: normal; padding: 13px 17px; } .q_tabs.vertical .tabs-nav li.active a { border: 2px solid #e3e3e3; padding: 11px 14px 11px 14px; position: relative; z-index: 100; } .q_tabs.vertical.left .tabs-nav li.active a { border-right-color: #fff; -webkit-border-top-left-radius: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-topleft: 4px; -moz-border-radius-bottomleft: 4px; border-top-left-radius: 4px; border-bottom-left-radius: 4px; } .q_tabs.vertical.right .tabs-nav li.active a { border-left-color: #fff; -webkit-border-top-right-radius: 4px; -webkit-border-bottom-right-radius: 4px; -moz-border-radius-topright: 4px; -moz-border-radius-bottomright: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; } .q_tabs.vertical .tabs-container { width: 73.68576709796673%; } .q_tabs.vertical.left .tabs-container { float: left; text-align: left; } .q_tabs.vertical.right .tabs-container { float: right; text-align: right; } .q_tabs.vertical .tab-content { position: relative; z-index: 50; } .q_tabs.vertical.left .tab-content { padding-left: 17px; border-left: 2px solid #e3e3e3; left: -2px; } .q_tabs.vertical.right .tab-content { padding-right: 17px; border-right: 2px solid #e3e3e3; right: -2px; } /* Boxed tabs styles ========================================================================== */ .q_tabs.boxed { text-align: left; } .q_tabs.boxed .tabs-nav { display: block; } .q_tabs.boxed .tabs-nav li a { border-bottom: none; position: relative; z-index: 200; } .q_tabs.boxed .tabs-nav li.active a { position: relative; z-index: 100; line-height: 40px; height: 40px; padding: 0 12px; border: 2px solid #e3e3e3; border-bottom-color: #fff; -webkit-border-top-left-radius: 3px; -moz-border-radius-topleft: 3px; border-top-left-radius: 3px; -webkit-border-top-right-radius: 3px; -moz-border-radius-topright: 3px; border-top-right-radius: 3px; } .q_tabs.boxed .tabs-container { overflow: hidden; text-align: left; padding: 19px 0 0; border-top: 2px solid #e3e3e3; position: relative; top: -2px; z-index: 50; } /* ========================================================================== Tabs shortcode end styles ========================================================================== */ /* ========================================================================== Accordion shortcode start styles ========================================================================== */ .q_accordion_holder{ position: relative; display: block; visibility: hidden; margin: 0 0 30px; } .q_accordion_holder.accordion.with_icon { border-top: 1px solid #eaeaea; } .q_accordion_holder.accordion .ui-accordion-header { cursor: pointer; position: relative; display: block; line-height: 2em; min-height: 45px; padding: 0; margin: 0 0 5px; -webkit-transform: translateZ(0px); -moz-transform: translateZ(0px); box-sizing: border-box; } .q_accordion_holder.accordion h3.ui-accordion-header { padding-top: 3px; } .q_accordion_holder.accordion h4.ui-accordion-header { padding-top: 5px; } .q_accordion_holder.accordion h5.ui-accordion-header { font-size: 14px; padding-top: 9px; } .q_accordion_holder.accordion h6.ui-accordion-header { padding-top: 10px; } .q_accordion_holder.accordion.with_icon h3.ui-accordion-header { padding-bottom: 3px; } .q_accordion_holder.accordion.with_icon h4.ui-accordion-header { padding-bottom: 5px; } .q_accordion_holder.accordion.with_icon h5.ui-accordion-header { padding-bottom: 9px; } .q_accordion_holder.accordion.with_icon h6.ui-accordion-header { padding-bottom: 10px; } .q_accordion_holder.accordion.with_icon .ui-accordion-header{ line-height: 3em; min-height: 3em; margin: 0; border: 1px solid #eaeaea; border-top: 0 !important; -webkit-transition: border-bottom 0.3s ease-in-out; -moz-transition: border-bottom 0.3s ease-in-out; -o-transition: border-bottom 0.3s ease-in-out; -ms-transition: border-bottom 0.3s ease-in-out; } .q_accordion_holder.accordion .ui-accordion-header, .q_accordion_holder.accordion.with_icon .ui-accordion-header { -webkit-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; color: #303030; font-weight: 600; text-transform: uppercase; letter-spacing: 1px; } .q_accordion_holder.accordion .ui-accordion-header:hover { color: #1abc9c; } .q_accordion_holder.accordion.with_icon .ui-accordion-header:last-child { border-bottom: 0 !important; } .q_accordion_holder.accordion.with_icon .ui-accordion-header span.tab-title { width: 72%; line-height: 1.5625em; margin: 0.85em 0 0.85em 20px; display: inline-block; } .q_accordion_holder.accordion.without_icon .ui-accordion-header span.tab-title{ padding: 0 0 0 63px; display: block; } .q_accordion_holder.accordion.with_icon .ui-state-active { border-bottom-color: transparent; -webkit-transition: border-bottom 0.3s ease-in-out; -moz-transition: border-bottom 0.3s ease-in-out; -o-transition: border-bottom 0.3s ease-in-out; -ms-transition: border-bottom 0.3s ease-in-out; } .q_accordion_holder.accordion.with_icon .ui-state-active, .q_accordion_holder.accordion .ui-state-active { -webkit-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; } .q_accordion_holder.accordion.with_icon .ui-accordion-header-active, .q_accordion_holder.with_icon div.accordion_content { background-color: #fbfbfb; } .q_accordion_holder.accordion.with_icon .ui-accordion-header div.icon-wrapper, .q_accordion_holder .ui-accordion-header .accordion_mark { float: left; line-height: 3.25em; position: relative; top: 0.09375em; } .q_accordion_holder.accordion.without_icon .ui-accordion-header div.icon-wrapper{ display: none !important; } .q_accordion_holder.accordion.with_icon .ui-accordion-header i{ margin: 0 0 0 15px; font-size: 18px; color: #1abc9c; } .q_accordion_holder.accordion .ui-accordion-header .accordion_mark_icon { display: block; width: 41px; height: 41px; background-image: url(img/plus.png); background-repeat: no-repeat; background-position: center; } .q_accordion_holder.with_icon .ui-accordion-header.ui-state-active .accordion_icon_mark{ background-image: url(img/minus.png); } .q_accordion_holder.accordion .ui-accordion-header .accordion_mark { display: block; width: 45px; height: 45px; border: 2px solid #e3e3e3; -webkit-border-radius: 3px; -moz-border-radius: 3px; -o-border-radius: 3px; -ms-border-radius: 3px; border-radius: 3px; background-color: transparent; transition: background-color 0.3s ease-in-out; box-sizing: border-box; } .q_accordion_holder.accordion .ui-accordion-header .accordion_mark:hover { background-image: url('img/button-bg-px.png') !important; } .q_accordion_holder.accordion .ui-accordion-header .accordion_mark.left_mark { position: absolute; top: 0; left: 0; } .q_accordion_holder.accordion .ui-accordion-header .accordion_mark.right_mark { position: absolute; right: 0.65em; top: 0.65em; } .q_accordion_holder.accordion.without_icon .ui-accordion-header .accordion_mark.right_mark, .q_accordion_holder.accordion.with_icon .ui-accordion-header .accordion_mark.left_mark { display: none; } .q_accordion_holder.accordion .ui-accordion-header.ui-state-active .accordion_mark_icon{ background-image: url(img/minus.png); } .q_accordion_holder.accordion .ui-accordion-header.ui-state-active .accordion_mark { background-color: #e3e3e3; transition: background-color 0.3s ease-in-out; } @media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { .q_accordion_holder.with_icon .accordion_icon_mark, .q_accordion_holder.accordion .ui-accordion-header .accordion_mark_icon{ -o-background-size: 9px 9px; -webkit-background-size: 9px 9px; -moz-background-size: 9px 9px; background-size: 9px 9px; background-image: url('img/plus@1_5x.png'); } .q_accordion_holder.with_icon .ui-accordion-header.ui-state-active .accordion_icon_mark, .q_accordion_holder.accordion .ui-accordion-header.ui-state-active .accordion_mark_icon{ -o-background-size: 9px 9px; -webkit-background-size: 9px 9px; -moz-background-size: 9px 9px; background-size:9px 9px; background-image: url('img/minus@1_5x.png'); } } @media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { .q_accordion_holder.with_icon .accordion_icon_mark, .q_accordion_holder.accordion .ui-accordion-header .accordion_mark_icon{ -o-background-size: 9px 9px; -webkit-background-size:9px 9px; -moz-background-size: 9px 9px; background-size: 9px 9px; background-image: url('img/plus@2x.png'); } .q_accordion_holder.with_icon .ui-accordion-header.ui-state-active .accordion_icon_mark, .q_accordion_holder.accordion .ui-accordion-header.ui-state-active .accordion_mark_icon{ -o-background-size: 9px 9px; -webkit-background-size: 9px 9px; -moz-background-size: 9px 9px; background-size: 9px 9px; background-image: url('img/minus@2x.png'); } } .q_accordion_holder.accordion div.accordion_content{ padding: 0 0 0 63px; margin: 0; } .q_accordion_holder.with_icon div.accordion_content { padding: 0 0 0 50px; border: 1px solid #eaeaea; border-top: 0; } .q_accordion_holder.accordion.with_icon div.accordion_content.no_icon{ padding: 0 0 0 22px; } .q_accordion_holder.accordion div.accordion_content_inner { padding: 8px 0 25px; display: block; } .q_accordion_holder.with_icon div.accordion_content_inner { padding: 10px 27px 19px 0; } /* Boxed accordion and toggle styles ========================================================================== */ .q_accordion_holder.boxed { } .q_accordion_holder.accordion.boxed .ui-accordion-header { text-align: center; background-color: #e3e3e3; } .q_accordion_holder.boxed .ui-accordion-header .accordion_mark { display: none; } .q_accordion_holder.boxed div.accordion_content { padding-left: 26px; } .q_accordion_holder.boxed div.accordion_content_inner { padding-top: 20px; } /* ========================================================================== Accordion shortcode end styles ========================================================================== */ /* ========================================================================== Highlight shortcode start styles ========================================================================== */ /*.highlight{ background-color: #1abc9c; color: #fff; padding: 0 3px; }*/ /* ========================================================================== Highlight shortcode end styles ========================================================================== */ .testimonials_holder { text-align: center; } .testimonials{ position: relative; } .testimonials .testimonial_container { overflow: hidden; width: 100%; background-color: transparent; text-align: left; margin: 0 0 16px; } .testimonials_holder .flex-direction-nav { display: block; position: static; } .testimonials_holder .flex-direction-nav li { display: inline-block; height: 30px; margin-top: 37px; } .testimonials_holder .flex-direction-nav li:first-child { margin-right: 5px; } .testimonials_holder .flex-direction-nav li:last-child { margin-left: 4px; } .testimonials_holder .flex-direction-nav a { position: relative; width: 30px; height: 30px; border: 2px solid #303030; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; opacity: 1; background-color: transparent; text-indent: -9999px; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } .testimonials_holder .flex-direction-nav a:hover { background-color: #303030; } .testimonials_holder.light .flex-direction-nav a { border-color: #fff; } .testimonials_holder.light .flex-direction-nav a:hover { background-color: #1abc9c; border-color: #1abc9c; } .testimonials_holder.light .flex-direction-nav a:before { color: #fff; } .testimonials_holder .flex-direction-nav a:before { font-family: 'FontAwesome', sans-serif; position: absolute; height: 26px; width: 26px; line-height: 26px; top: 0; left: 0; color: #000; text-indent: 0; font-size: 16px; } .testimonials_holder .flex-direction-nav a:hover:before { color: #fff; } .testimonials_holder .flex-direction-nav a.flex-prev:before { content: '\f104'; } .testimonials_holder .flex-direction-nav a.flex-next:before { content: '\f105'; } .testimonials_holder.full_width { background: none; } .content .testimonial_content .container .container_inner { padding:0px 0px 0px 0px; } .testimonial_text_holder { position: relative; display: block; } .testimonials .author_image_holder { margin-left: 15px; position: relative; } .author_image_holder .image_holder { border-radius: 3em; border: 1px solid #eaeaea; width: 60px; height: 60px; display: inline-block; float: left; margin:0 15px 0 0; overflow: hidden; } .testimonials .testimonial_text_inner p.testimonial_author { font-size: 13px; color: #303030; margin-top: 22px; font-weight: 500; } .testimonials .testimonial_text_inner p.testimonial_author span.author_company { color: #1abc9c; } .testimonial_content_inner .testimonial_author .website{ color:#303030; font-weight:300; display:block; } .testimonial_content_inner .testimonial_author h4{ color:#00a8e8; } .testimonial_text_inner .testimonial_name { display: block; } .testimonial_content_inner .testimonial_author .company_position { color: #1abc9c; } .testimonials .testimonial_text_inner { display: block; } .testimonials .testimonial_text_inner p { line-height: 1.666666666666667em; /* 35px / 13px */ font-size: 21px; } .testimonials_holder.standard .testimonials .testimonial_text_inner{ -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; } .testimonials_holder.full_width .testimonials .testimonial_text_inner{ border-left:none; border-right:none; position:relative; text-align:center; } .testimonials_holder.full_width .testimonials .testimonial_text_inner p{ margin: 0 0 19px; } .testimonial_arrow { width: 20px; height: 20px; display: inline-block; margin: 0 0 0 -10px; z-index: 999; position: relative; overflow: hidden; left: 45px; bottom: 11px; background-color: #fbfbfb; border-width: 0 1px 1px 0; border-style: solid; border-color: #eaeaea; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); } .testimonials.transparent .testimonial_text_inner { background-color: transparent !important; padding: 0; border: none; } .testimonial_image_holder { text-align: center; display: inline-block; position: relative; overflow: hidden; vertical-align: middle; margin: 0 0 50px; } .testimonial_image_holder img{ vertical-align: middle; } /* ========================================================================== Blockquote shortcode start styles ========================================================================== */ blockquote { position: relative; padding: 14px 14px 14px 10px; border-left: 4px solid transparent; } blockquote h5 { line-height: 1.5625em; text-transform: none; font-size: 21px; letter-spacing: normal; font-weight: 400; margin: 0 !important; } blockquote.with_quote_icon h5 { padding: 0 0 0 40px; } blockquote i.pull-left { font-size: 22px; color: #c1c0c0; margin: 6px 0 0 !important; } /* ========================================================================== Blockquote shortcode end styles ========================================================================== */ /* ========================================================================== Gallery shortcode styles ========================================================================== */ .gallery_holder{ display: block; position: relative; } .wpb_image_grid .gallery_holder{ width: 100.1%; } .gallery_holder ul{ list-style: none; display: block; width: 100%; position: relative; margin: 0; padding: 0; } .gallery_holder ul li{ position: relative; display: block; float: left; overflow: hidden; } .gallery_holder ul li a{ display: block; position: relative; -webkit-backface-visibility: hidden; } .gallery_holder ul li a { display: block; overflow: hidden; -webkit-transform: translateZ(0px); -moz-transform: translateZ(0px); } .wpb_image_grid .gallery_holder ul li a { margin-right: -1px; margin-bottom: -1px !important; } .gallery_holder ul li a img { display: block; width: 100%; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; -webkit-transform: scale(1, 1); -moz-transform: scale(1, 1); -ms-transform: scale(1, 1); -o-transform: scale(1, 1); transform: scale(1, 1); } .gallery_holder ul li.grayscale a img { -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); filter: gray; filter: grayscale(100%); filter: url(img/desaturate.svg#grayscale); } .gallery_holder ul li.grayscale:hover a img { -webkit-filter: grayscale(0); filter: none; } .gallery_holder ul li:hover a img { -webkit-transform: scale(1.03, 1.03); -moz-transform: scale(1.03, 1.03); -ms-transform: scale(1.03, 1.03); -o-transform: scale(1.03, 1.03); transform: scale(1.03, 1.03); } .gallery_holder ul li .gallery_hover{ position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; display: inline-block; background-color: #000; background-color: rgba(0, 0, 0, 0.81); visibility: visible; opacity: 0; filter: alpha(opacity=0); -webkit-transition: opacity .4s; -moz-transition: opacity .4s; -o-transition: opacity .4s; -ms-transition: opacity .4s; -webkit-transform: translateZ(0px); -moz-transform: translateZ(0px); -webkit-backface-visibility: hidden; z-index: 1000; } .gallery_holder ul li:hover .gallery_hover{ opacity: 1; filter: alpha(opacity=100); } .gallery_holder ul li .gallery_hover i{ position: absolute; top: 50%; left: 50%; margin: -15px 0 0 -15px; font-size: 30px; color: #fff; width: 30px; height: 30px; line-height:30px; text-align: center; display: inline-block; } .gallery_holder ul.v5 li, .wpb_gallery_slides .gallery_holder ul.v5 li{ width: 20%; margin: 0; } .gallery_holder ul.v4 li, .wpb_gallery_slides .gallery_holder ul.v4 li{ width: 25%; margin: 0; } .gallery_holder ul.v3 li, .wpb_gallery_slides .gallery_holder ul.v3 li{ width: 33.33333333333333%; margin: 0; } .gallery_holder ul.v2 li, .wpb_gallery_slides .gallery_holder ul.v2 li{ width: 50%; margin: 0; } /*With space gallery*/ .gallery_holder .gallery_with_space ul li, .wpb_gallery_slides .gallery_holder .gallery_with_space ul li{ margin-bottom: 2%; } .gallery_holder .gallery_with_space ul li:last-child, .wpb_gallery_slides .gallery_holder .gallery_with_space ul li:last-child{ margin-bottom: 0; } .gallery_holder ul.gallery_with_space.v2 li, .wpb_gallery_slides .gallery_holder ul.gallery_with_space.v2 li { width: 49%; margin: 0 2% 2% 0; } .gallery_holder ul.gallery_with_space.v2 li:nth-child(2n), .wpb_gallery_slides .gallery_holder ul.gallery_with_space.v2 li:nth-child(2n){ margin-right: 0; } .gallery_holder ul.gallery_with_space.v3 li, .wpb_gallery_slides .gallery_holder ul.gallery_with_space.v3 li{ width: 32%; margin: 0 2% 2% 0; } .gallery_holder ul.gallery_with_space.v3 li:nth-child(3n), .wpb_gallery_slides .gallery_holder ul.gallery_with_space.v3 li:nth-child(3n){ margin-right: 0; } .gallery_holder ul.gallery_with_space.v4 li, .wpb_gallery_slides .gallery_holder ul.gallery_with_space.v4 li{ width: 23.5%; margin: 0 2% 2% 0; } .gallery_holder ul.gallery_with_space.v4 li:nth-child(4n), .wpb_gallery_slides .gallery_holder ul.gallery_with_space.v4 li:nth-child(4n){ margin-right: 0; } .gallery_holder ul.gallery_with_space.v5 li, .wpb_gallery_slides .gallery_holder ul.gallery_with_space.v5 li{ width: 18.4%; margin: 0 2% 2% 0; } .gallery_holder ul.gallery_with_space.v5 li:nth-child(5n), .wpb_gallery_slides .gallery_holder ul.gallery_with_space.v5 li:nth-child(5n){ margin-right: 0; } /* ========================================================================== Enf of gallery shortcode styles ========================================================================== */ /* ========================================================================== Single image shortcode styles ========================================================================== */ .wpb_content_element.wpb_single_image img{ vertical-align: middle; } /* ========================================================================== Enf of single image shortcode styles ========================================================================== */ /* ========================================================================== Dropcaps shortcodes styles ========================================================================== */ .q_dropcap{ position: relative; display: inline-block; float: left; height: 48px; width: 48px; line-height: 48px; font-size: 23px; color: #1abc9c; text-align: center; margin: 5px 20px 0 0; border: 1px solid transparent; } .q_dropcap.circle, .q_dropcap.square{ margin: 5px 20px 0 0; font-size: 22px; background-color: #1abc9c; border: 1px solid transparent; color: #fff; font-weight: 300; } .q_dropcap.normal{ font-weight: 700; position: relative; left: 8px; } .q_dropcap.circle { -webkit-border-radius: 2em; -moz-border-radius: 2em; -ms-border-radius: 2em; -o-border-radius: 2em; border-radius: 2em; } .q_dropcap.square { -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; } /* ========================================================================== Message box shortcode styles ========================================================================== */ .q_message { position: relative; padding: 26px 30px; color: #fff; background-color: #1abc9c; } .q_message .q_message_inner{ position: relative; } .q_message.with_icon .q_message_icon_holder{ float:left; padding:0 27px 0 0; } .q_message.with_icon .q_message_icon{ display: table; height: 100%; } .q_message.with_icon .q_message_icon_inner { display: table-cell; height: 100%; vertical-align: middle; } .q_message.with_icon > i { line-height: 1em; } .q_message.with_icon img { float: left; } .q_message a.close { position: absolute; top: -19px; right: -23px; line-height: 13px; color: #fff; } .q_message a.close i { width: 14px; height: 14px; display: inline-block; background-repeat: no-repeat; background-position: center; } .q_message .message_text { display: table; height: 100%; font-weight: 700; font-size: 18px; text-transform: uppercase; letter-spacing: 1px; } .q_message .message_text_holder { padding: 0px 20px 0px 0px; } .q_message .message_text_inner { display: table-cell; height: 100%; vertical-align: middle; } .q_message.with_icon .message_text_holder { padding: 0px 20px 0px 0px; } /* ========================================================================== Pricing table shorcode styles ========================================================================== */ .q_price_table { position: relative; width: 100%; padding: 0; color: #fff; border-top: 1px solid #ebebeb; margin-left: 2.5%; float: left; } .qode_pricing_tables.two_columns .q_price_table { width: 48.75%; } .qode_pricing_tables.three_columns .q_price_table { width: 31.666666666666668%; } .qode_pricing_tables.four_columns .q_price_table { width: 23.125%; } .qode_pricing_tables .q_price_table:first-child { margin-left: 0; } .q_price_table .price_table_inner { background-color: #262626; position: relative; } .q_price_table.active .active_text { position: absolute; top: 0; left: 0; width: 100%; text-align: center; background-color: #1abc9c; font-size: 13px; line-height: 31px; } .q_price_table.active .price_table_inner > ul { padding: 31px 0 0; margin: -31px 0; } .price_table_inner ul { list-style: none outside none; margin: 0; padding-left: 0 !important; } .price_table_inner ul li { text-align: center; margin: 0; padding: 2px 20px 13px; } .price_table_inner ul li.pricing_table_content { padding: 20px 27px 10px; } .price_table_inner ul li.pricing_table_content li { font-size: 13px; } .price_table_inner ul li.pricing_table_content li:last-child { border-bottom: none; } .price_table_inner ul li.prices { padding-top: 0; padding-bottom: 3px; } .price_table_inner ul li.table_title { padding: 25px 25px 3px; } .price_table_inner ul li.table_title .title_content { color: #fff; font-weight: 700; font-size: 17px; } .price_in_table { text-align: center; } .price_in_table .value { font-size: 20px; font-weight: 600; vertical-align: top; position: relative; top: 17px; } .price_in_table .price { font-size: 83px; line-height: 1em; padding: 0 3px; font-weight: 200; vertical-align: middle; } .price_in_table .mark { vertical-align: bottom; position: relative; font-size: 16px; font-weight: 600; text-transform: uppercase; top: 10px; } .price_table_inner .price_button{ padding: 0 0 32px; } .price_button .qbutton{ margin:0 7px; } /* ========================================================================== Icon with text shortcode start styles ========================================================================== */ .q_icon_with_title{ display: block; position: relative; } .q_icon_with_title .icon_holder { display: inline-block; position: relative; z-index: 2; } .q_icon_with_title:not(.right) .icon_holder { float: left; } .q_icon_with_title.right .icon_holder { float: right; } .q_icon_with_title .icon_text_holder .icon_title { display: block; margin: 0 0 1.08em; font-weight: 600; } .q_icon_with_title.large .icon_text_holder .icon_title { margin-bottom: 0.35em; } .q_icon_with_title .icon_with_title_link { display: inline-block; margin: 13px 0 0; color: #1abc9c; } .q_icon_with_title .icon_with_title_link:hover { color: #303030; } .q_icon_with_title .icon_holder.q_icon_animation, .box_holder_icon_inner.q_icon_animation{ -webkit-transform: scale(0); -moz-transform: scale(0); -ms-transform: scale(0); -o-transform: scale(0); transform: scale(0); -webkit-transition: all 0.4s ease; -moz-transition: all 0.4s ease; -o-transition: all 0.4s ease; transition: all 0.4s ease; -webkit-backface-visibility: hidden; } .q_icon_with_title .icon_holder.q_icon_animation.q_show_animation, .box_holder_icon_inner.q_icon_animation.q_show_animation{ -webkit-transform: scale(1.0); -moz-transform: scale(1.0); -ms-transform: scale(1.0); -o-transform: scale(1.0); transform: scale(1.0); } .q_icon_with_title .icon_holder .fa-stack, .box_holder_icon_inner .fa-stack, .q_font_awsome_icon_square, .q_font_awsome_icon_stack i.fa-stack-base { border: 2px solid #c0c0c0; -webkit-transition: all 0.1s linear; -moz-transition: all 0.1s linear; -ms-transition: all 0.1s linear; -o-transition: all 0.1s linear; transition: all 0.1s linear; -webkit-backface-visibility: hidden; -webkit-box-sizing: initial; -moz-box-sizing: initial; box-sizing: initial; } .q_font_awsome_icon_stack i.fa-stack-base{ border:none; } .q_icon_with_title .icon_text_holder{ position: relative; } .q_icon_with_title span.fa-stack .qode_iwt_icon_element, .q_box_holder.with_icon span.fa-stack .qode_iwt_icon_element { font-size: 0.7em; color: #c0c0c0; -webkit-transition: all 0.1s linear; -moz-transition: all 0.1s linear; -ms-transition: all 0.1s linear; -o-transition: all 0.1s linear; transition: all 0.1s ease-in-out; } .q_icon_with_title.circle span.fa-stack .qode_iwt_icon_element { font-size: 0.9em; } .q_icon_with_title span.fa-stack.custom-font .qode_iwt_icon_element { font-size: 0.7em; } .q_icon_with_title .icon_text_inner{ padding: 0 0 18px; } .q_icon_with_title .icon_title_holder { display: table; width: 100%; height: 100%; margin:0 0 12px; } .q_icon_with_title .icon_title_holder .icon_holder{ display: table-cell; text-align: center; height: 100%; vertical-align: middle; float:none; padding:0 15px 0 0; box-sizing: content-box; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; } .q_icon_with_title .icon_title_holder .icon_holder > span { position: relative; top: 2px; } .q_icon_with_title .icon_text_holder .icon_title_holder .icon_title { display: table-cell; margin: 0 0 0; vertical-align: middle; width: 100%; } .q_font_awsome_icon_square .qode_icon_element { color: #fff; } .q_font_awsome_icon_stack .qode_icon_element { color: #fff; } .qode_icon_shortcode.fa-stack a { display: block; width: 100%; height: 100%; } .qode_icon_shortcode.fa-stack .qode_icon_element { display: block; line-height: inherit; } .touch .no_animation_on_touch .q_icon_animation{ -webkit-transform: scale(1.0); -moz-transform: scale(1.0); -ms-transform: scale(1.0); -o-transform: scale(1.0); transform: scale(1.0); } /* Icon center styles ========================================================================== */ /** * Styles when icon is in center. Can be in a box or not */ .q_icon_with_title.center{ text-align: center; } .q_icon_with_title.center.center .icon_holder{ float: none; display: block; margin: 0 0 20px; } .q_icon_with_title.custom_icon_image.center .icon_holder{ margin: 0 0 13px; } .q_icon_with_title.center .icon_holder{ width: 100% !important; } .q_icon_with_title.center .icon_holder .font_awsome_icon i { color: #7b7b7b; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; } .q_icon_with_title.center .icon_holder .font_awsome_icon i:hover { color: #1abc9c; } /* End of icon center styles ========================================================================== */ /* Generic icon styles ========================================================================== */ .q_icon_with_title.boxed .icon_holder .fa-stack, .q_font_awsome_icon_square { background-color: #1abc9c; border-radius: 4px; text-align: center; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; -webkit-backface-visibility: hidden; } .q_box_holder.with_icon .box_holder_icon_inner .fa-stack i.fa-stack-base{ color: #1abc9c; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; -webkit-backface-visibility: hidden; } .q_icon_with_title.square .icon_holder .fa-stack, .box_holder_icon_inner.square .fa-stack { -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .q_font_awsome_icon_square{ -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .q_icon_with_title.square .icon_holder .fa-stack:hover, .box_holder_icon_inner.square .fa-stack:hover, .box_holder_icon_inner.circle .fa-stack:hover, .circle .icon_holder .fa-stack:hover{ background-color: #1abc9c; border-color: transparent !important; } .q_font_awsome_icon_stack .fa-circle, .q_icon_with_title.boxed .icon_holder .fa-stack { color: #1abc9c; -webkit-transition: color 0.4s ease-in-out; -moz-transition: color 0.4s ease-in-out; -o-transition: color 0.4s ease-in-out; transition: color 0.4s ease-in-out; } .q_icon_with_title.circle .icon_holder .fa-stack:hover i.fa-circle, .q_font_awsome_icon_stack:hover .fa-circle, .q_box_holder.with_icon .box_holder_icon_inner .fa-stack:hover i.fa-stack-base { color: #f3f3f3 !important; } .q_icon_with_title.boxed .icon_holder .fa-stack { -webkit-transition: background-color 0.2s ease-in-out; -moz-transition: background-color 0.2s ease-in-out; -o-transition: background-color 0.2s ease-in-out; transition: background-color 0.2s ease-in-out; } .q_icon_with_title.circle .icon_holder .fa-stack:hover .qode_iwt_icon_element, .q_icon_with_title.square .icon_holder .fa-stack:hover .qode_iwt_icon_element, .q_font_awsome_icon_stack:hover i:last-child, .q_icon_with_title.boxed .icon_holder .fa-stack:hover i, .q_box_holder.with_icon span.fa-stack:hover i:last-child, .q_icon_with_title.square .icon_holder .fa-stack:hover i, .box_holder_icon_inner.square:hover i, .q_font_awsome_icon_square:hover i { color: #fff; } .q_box_holder.with_icon .tiny span.fa-stack i:last-child { top: 1px; } .q_icon_with_title.with_border_line .icon_text_inner{ border-bottom: 1px solid #fbfbfb; } .q_icon_with_title.tiny .icon_text_holder { padding: 0 0 0 44px; } .q_icon_with_title.small .icon_text_holder{ padding: 0 0 0 46px; } .q_icon_with_title.left_from_title .icon_text_holder{ padding: 0; } .q_icon_with_title.medium .icon_holder, .q_icon_with_title.tiny.square .icon_holder, .q_icon_with_title.small.square .icon_holder{ text-align: center; } .q_icon_with_title.tiny.square .icon_text_holder, .q_icon_with_title.medium .icon_text_holder { padding: 0 0 0 56px; } .q_icon_with_title.large .icon_text_holder{ padding: 0 0 0 65px; } .q_icon_with_title.large .icon_holder{ text-align: center; } .q_icon_with_title.very_large .icon_text_holder{ padding: 0 0 0 84px; } .q_icon_with_title.tiny.boxed .icon_text_holder, .q_icon_with_title.tiny.circle .icon_text_holder, .q_icon_with_title.tiny.custom_icon_image .icon_text_holder{ padding: 0 0 0 55px; } .q_icon_with_title.small.square .icon_text_holder, .q_icon_with_title.small.boxed .icon_text_holder, .q_icon_with_title.small.circle .icon_text_holder, .q_icon_with_title.small.custom_icon_image .icon_text_holder{ padding: 0 0 0 72px; } .q_icon_with_title.medium.circle .icon_text_holder { padding: 0 0 0 119px; } .q_icon_with_title.medium.boxed .icon_text_holder, .q_icon_with_title.medium.custom_icon_image .icon_text_holder, .q_icon_with_title.medium.square .icon_text_holder{ padding: 0 0 0 95px; } .q_icon_with_title.large.boxed .icon_text_holder, .q_icon_with_title.large.circle .icon_text_holder, .q_icon_with_title.large.custom_icon_image .icon_text_holder, .q_icon_with_title.large.square .icon_text_holder{ padding: 0 0 0 122px; } .q_icon_with_title.very_large.boxed .icon_text_holder, .q_icon_with_title.very_large.circle .icon_text_holder, .q_icon_with_title.very_large.custom_icon_image .icon_text_holder, .q_icon_with_title.very_large.square .icon_text_holder{ padding: 0 0 0 150px; } .q_icon_with_title.left_from_title .icon_text_holder{ padding: 0 0 0 0px !important; } .q_icon_with_title.right .icon_text_holder { padding-left: 0 !important; text-align: right; } .q_icon_with_title.tiny.circle.right .icon_text_holder, .q_icon_with_title.tiny.custom_icon_image.right .icon_text_holder{ padding: 0 55px 0 0; } .q_icon_with_title.small.square.right .icon_text_holder, .q_icon_with_title.small.circle.right .icon_text_holder, .q_icon_with_title.small.custom_icon_image.right .icon_text_holder { padding: 0 72px 0 0; } .q_icon_with_title.medium.circle.right .icon_text_holder { padding: 0 119px 0 0; } .q_icon_with_title.medium.custom_icon_image.right .icon_text_holder, .q_icon_with_title.medium.square.right .icon_text_holder{ padding: 0 95px 0 0; } .q_icon_with_title.large.circle.right .icon_text_holder, .q_icon_with_title.large.custom_icon_image.right .icon_text_holder, .q_icon_with_title.large.square.right .icon_text_holder{ padding: 0 122px 0 0; } .q_icon_with_title.very_large.circle.right .icon_text_holder, .q_icon_with_title.very_large.custom_icon_image.right .icon_text_holder, .q_icon_with_title.very_large.square.right .icon_text_holder{ padding: 0 150px 0 0; } .q_icon_with_title.tiny.square.right .icon_text_holder { padding: 0 56px 0 0; } .q_icon_with_title.left_from_title .icon_text_holder .icon_holder{ width: auto !important; } .q_icon_with_title.left_from_title.custom_icon_image.tiny .icon_text_holder .icon_holder{ width: 35px !important; } .q_icon_with_title.left_from_title.custom_icon_image.small .icon_text_holder .icon_holder{ width: 52px !important; } .q_icon_with_title.left_from_title.custom_icon_image.medium .icon_text_holder .icon_holder{ width: 78px !important; } .q_icon_with_title.left_from_title.custom_icon_image.large .icon_text_holder .icon_holder{ width: 104px !important; } .q_icon_with_title.left_from_title.custom_icon_image.very_large .icon_text_holder .icon_holder{ width: 130px !important; } .q_icon_with_title.tiny.center .icon_text_holder, .q_icon_with_title.small.center .icon_text_holder, .q_icon_with_title.medium.center .icon_text_holder, .q_icon_with_title.large.center .icon_text_holder, .q_icon_with_title.very_large.center .icon_text_holder, .q_icon_with_title.tiny.boxed.center .icon_text_holder, .q_icon_with_title.tiny.circle.center .icon_text_holder, .q_icon_with_title.small.boxed.center .icon_text_holder, .q_icon_with_title.small.circle.center .icon_text_holder, .q_icon_with_title.medium.boxed.center .icon_text_holder, .q_icon_with_title.medium.circle.center .icon_text_holder, .q_icon_with_title.large.boxed.center .icon_text_holder, .q_icon_with_title.large.circle.center .icon_text_holder, .q_icon_with_title.very_large.boxed.center .icon_text_holder, .q_icon_with_title.very_large.circle.center .icon_text_holder, .q_icon_with_title.tiny.custom_icon_image.center .icon_text_holder, .q_icon_with_title.small.custom_icon_image.center .icon_text_holder, .q_icon_with_title.medium.custom_icon_image.center .icon_text_holder, .q_icon_with_title.large.custom_icon_image.center .icon_text_holder, .q_icon_with_title.very_large.custom_icon_image.center .icon_text_holder{ padding: 0; } .q_icon_with_title.left_from_title .icon_holder{ display: block; } .q_icon_with_title.tiny .icon_holder img, .q_icon_with_title.left_from_title.tiny .icon_holder, .q_icon_with_title.left_from_title.small.normal_icon .icon_holder{ width: 35px; } .q_icon_with_title.small .icon_holder img, .q_icon_with_title.left_from_title.small .icon_holder, .q_icon_with_title.left_from_title.large.normal_icon .icon_holder{ width: 52px; } .q_icon_with_title.medium .icon_holder img, .q_icon_with_title.left_from_title.medium .icon_holder, .q_icon_with_title.left_from_title.very_large.normal_icon .icon_holder{ width: 78px; } .q_icon_with_title.large .icon_holder img, .q_icon_with_title.left_from_title.large .icon_holder{ width: 104px; } .q_icon_with_title.very_large .icon_holder img, .q_icon_with_title.left_from_title.very_large .icon_holder{ width: 130px; } .q_icon_with_title.left_from_title.tiny.normal_icon .icon_holder{ width: 25px; } .q_icon_with_title.left_from_title.medium.normal_icon .icon_holder{ width: 45px; } /* End of generic icon center styles ========================================================================== */ .q_icon_with_title.circle .qode_iwt_icon_holder .qode_iwt_icon_element, .q_icon_with_title.square .qode_iwt_icon_holder .qode_iwt_icon_element { display: block; height: 100%; line-height: inherit; text-align: center; } /* ========================================================================== End if icon with text shortcode styles ========================================================================== */ /* ========================================================================== Icon start shortcode ========================================================================== */ .q_font_awsome_icon { display: inline-block; } .q_font_awsome_icon i, .q_font_awsome_icon span { color: #1abc9c; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; -webkit-backface-visibility: hidden; } .q_font_awsome_icon i:hover, .q_font_awsome_icon span:hover { color: #1abc9c; } .q_font_awsome_icon.pull-center{ display: block; text-align: center; } .q_font_awsome_icon_square.pull-center, .q_font_awsome_icon_stack.pull-center{ display: block; margin: 0 auto !important; } .q_font_awsome_icon.q_icon_animation, .q_font_awsome_icon_square.q_icon_animation, .q_font_awsome_icon_stack.q_icon_animation{ -webkit-transform: scale(0); -moz-transform: scale(0); -ms-transform: scale(0); -o-transform: scale(0); transform: scale(0); -webkit-transition: -webkit-transform 0.4s ease; -moz-transition: -moz-transform 0.4s ease; -o-transition: -o-transform 0.4s ease; -ms-transition: -ms-transform 0.4s ease; transition: transform 0.4s ease; -webkit-backface-visibility: hidden; } .q_font_awsome_icon.q_icon_animation.q_show_animation, .q_font_awsome_icon_square.q_icon_animation.q_show_animation, .q_font_awsome_icon_stack.q_icon_animation.q_show_animation{ -webkit-transform: scale(1.0); -moz-transform: scale(1.0); -ms-transform: scale(1.0); -o-transform: scale(1.0); transform: scale(1.0); } #back_to_top span, .q_social_icon_holder .fa-stack, .q_icon_with_title.square .icon_holder .fa-stack, .box_holder_icon_inner.square .fa-stack { text-align: center; } /* ========================================================================== Icon end shortcode ========================================================================== */ .drop_down .wide .second ul li div.flexslider li:nth-child(4n+1){ clear: none; } .drop_down .wide .second ul li .flexslider ul { padding:0; border:none; } .drop_down .wide .second ul li ul.flex-direction-nav a{ position:absolute; top:0; border:none; margin:0px 0 0 0; } .drop_down .wide .second ul li ul.flex-direction-nav{ position:absolute; top:45px; left:0px; overflow:visible; width: 100%; } .drop_down .wide .second ul li div.flexslider{ margin: 0; } .drop_down .wide .second ul li .flexslider.widget_flexslider ul.flex-direction-nav li{ width: 100%; } .flexslider.widget_flexslider h3, .drop_down .wide .second ul li ul li .flexslider.widget_flexslider h3, .drop_down .wide .second ul li ul li .flexslider.widget_flexslider h3 a{ color: #fff; font-size: 15px; font-weight: 400; line-height: 22px; padding: 10px 0 2px !important; } .flexslider.widget_flexslider ul li h3 a, .drop_down .wide .second .inner ul li.flexslider.widget_flexslider ul li h3 a{ color: #000; font-size: 18px; font-weight: 300; line-height: 22px; } .flexslider.widget_flexslider ul.flex-direction-nav a.flex-prev, .drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider ul.flex-direction-nav a.flex-prev{ background-color: #000; background-color: rgba(0, 0, 0, 0.4); width: 40px; height: 40px; line-height: 40px; } .drop_down .second .flexslider.widget_flexslider ul.flex-direction-nav i { display:inline; } .drop_down .wide.icons .second .flexslider.widget_flexslider ul.flex-direction-nav i { width:auto; float:none; height:auto; color: #fff; } .flexslider.widget_flexslider ul.flex-direction-nav a.flex-next, .drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider ul.flex-direction-nav a.flex-next{ background-color: #000; background-color: rgba(0, 0, 0, 0.4); width: 40px; height: 40px; line-height: 40px; } .flexslider.widget_flexslider ul.flex-direction-nav a.flex-next:hover, .drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider ul.flex-direction-nav a.flex-next:hover, .flexslider.widget_flexslider ul.flex-direction-nav a.flex-prev:hover, .drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider ul.flex-direction-nav a.flex-prev:hover{ background-color:#000; } .drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider .menu_recent_post_text { padding: 10px 0; } .drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider .menu_recent_post_text a{ display: inline; padding: 0; } .drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider .menu_recent_post_text a:hover{ color:#fff; } .drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider a, .drop_down .wide .second ul li .flexslider.widget_flexslider a{ padding: 0; margin: 0; } .drop_down .wide .second .inner ul li.sub .flexslider.widget_flexslider a i, .drop_down .wide .second ul li .flexslider.widget_flexslider a i{ font-size: 20px; } ul.flickr_widget{ display: inline-block; position: relative; padding:0; } ul.flickr_widget li{ float: left; margin: 0px 5px 5px 0px; } ul.flickr_widget li:nth-child(3n){ margin: 0 0 5px; } ul.flickr_widget li a img{ float: left; } .menu_recent_post_text{ display: block; } .menu_recent_post_text a{ display: inline-block !important; color: #fff !important; } /* ========================================================================== Icon progress bar shortcode start styles ========================================================================== */ .q_progress_bars_icons{ display: block; position: relative; opacity: 0; filter: alpha(opacity=0); } .q_progress_bars_icons_inner{ position: relative; width: 100%; } .q_progress_bars_icons_inner .bar{ position: relative; float: left; margin: 0px 10px 10px 0px; } .q_progress_bars_icons_inner.normal .bar{ margin: 0 0 10px; } .q_progress_bars_icons_inner.tiny .bar{ height: 39px; width: 39px; } .q_progress_bars_icons_inner.small .bar{ width: 56px; height: 56px; } .q_progress_bars_icons_inner.medium .bar{ width: 83px; height: 83px; } .q_progress_bars_icons_inner.large .bar{ width: 109px; height: 109px; } .q_progress_bars_icons_inner.very_large .bar{ width: 135px; height: 135px; } .q_progress_bars_icons_inner .bar .bar_noactive, .q_progress_bars_icons_inner .bar .bar_active{ display: inline-block; position: absolute; top: 0px; left: 0px; overflow: hidden; z-index: 50; } .q_progress_bars_icons_inner .bar.active .bar_noactive { z-index: 100; } .q_progress_bars_icons_inner.square .bar .bar_noactive, .q_progress_bars_icons_inner.square .bar .bar_active{ border: 1px solid #d7d7d7; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; } .q_progress_bars_icons_inner.circle .bar .bar_noactive, .q_progress_bars_icons_inner.circle .bar .bar_active { border: 1px solid #d7d7d7; -webkit-border-radius: 2em; -moz-border-radius: 2em; -ms-border-radius: 2em; -o-border-radius: 2em; border-radius: 2em; } .q_progress_bars_icons_inner.square .bar.active .bar_noactive, .q_progress_bars_icons_inner.square .bar.active .bar_active, .q_progress_bars_icons_inner.circle .bar.active .bar_noactive, .q_progress_bars_icons_inner.circle .bar.active .bar_active { border: 1px solid #1abc9c; } .q_progress_bars_icons_inner.square .bar.active i, .q_progress_bars_icons_inner.circle .bar.active i, .q_progress_bars_icons_inner.normal .bar.active i, .q_progress_bars_icons_inner .bar.active i.fa-circle{ color: #1abc9c; } .q_progress_bars_icons_inner.square .bar i, .q_progress_bars_icons_inner.circle .bar i, .q_progress_bars_icons_inner.normal .bar i, .q_progress_bars_icons_inner .bar i.fa-circle{ color: #d7d7d7; } /* ========================================================================== Icon progress bar shortcode end styles ========================================================================== */ .more_facts_outer{ position: relative; display: block; height: 0; overflow: hidden; } .more_facts_inner_holder{ position: relative; display: inline-block; width: 100%; vertical-align: middle; } .more_facts_inner{ display: inline-block; width: 100%; padding: 70px 0 0; position: relative; } .more_facts_holder{ background-color: #f6f6f6; } .more_facts_button { display: block; position: relative; margin: 0; padding: 39px 0 15px; color: #303030; font-size: 19px; line-height: 22px; cursor: pointer; z-index: 90; } .more_facts_button:hover{ color: #1abc9c; } .more_facts_button .more_facts_button_text, .more_facts_button .more_facts_button_arrow{ display: block; } .more_facts_button .more_facts_button_text{ display: block; font-size: 17px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; padding: 0px 0 5px; } .more_facts_button .more_facts_button_arrow{ -webkit-transition: -webkit-transform 300ms ease-in-out; -moz-transition: -moz-transform 300ms ease-in-out; -ms-transition: -ms-transform 300ms ease-in-out; -o-transition: -o-transform 300ms ease-in-out; transition: transform 300ms ease-in-out; } .more_facts_button .more_facts_button_arrow.rotate_arrow { -webkit-transform: rotate(-180deg); -moz-transform: rotate(-180deg); -ms-transform: rotate(-180deg); -o-transform: rotate(-180deg); transform: rotate(-180deg); } .more_facts_button_holder{ display: block; position: relative; } .more_facts_button_holder.left{ text-align: left; } .more_facts_button_holder.center{ text-align: center; } .more_facts_button_holder.right{ text-align: right; } /* ========================================================================== Oblique section styles ========================================================================== */ .angled-section { position: absolute; z-index: 20; display:block; } .angled-section polygon{ fill: #f6f6f6; } .angled-section.svg-top { top: -85px; } .angled-section.svg-bottom { bottom: -85px; } .angled-section.svg-footer-bottom { bottom: 0; } .angled-section.svg-title-bottom { bottom: 0; } /* ========================================================================== End of Oblique section styles ========================================================================== */ .ordered ul, .ordered ol { counter-reset: li; display: block; list-style-type: decimal; background-position: left center; background-repeat: no-repeat; margin: 0 0 30px; padding: 0 0 0 20px; } .ordered ol li { margin: 0px 0px 21px; padding: 0 0 0 4px; color: #303030; } /* ========================================================================== Unordered list shortcode styles ========================================================================== */ .q_list.normal ul > li { font-weight: 400 !important; } .q_list.light ul > li { font-weight: 300 !important; } .q_list.bold ul > li { font-weight: 600 !important; } .q_list.circle ul, .q_list.number ul{ display: block; list-style-type: none; margin: 0; padding: 0; } .q_list.number ul{ counter-reset: li; } .q_list.number.circle_number li { padding-left: 43px; margin-bottom: 22px; } .q_list.circle ul>li, .q_list.number ul>li{ position: relative; font-weight: 400; margin: 0 0 22px; padding: 0 0 0 22px; color: #303030; } .q_list.circle ul>li:before { position: absolute; left: 0; width: 7px; height: 7px; top: 9px; background-color: #ababab; display: block; content: ''; border-radius: 25px; } .q_list.number ul>li:before{ height: 20px; width: 20px; line-height: 20px; display: inline-block; position: absolute; left: 0; top: 1px; padding: 0; color: #1abc9c; text-align: center; content: counter(li, decimal-leading-zero); counter-increment: li; font-weight: 500; } .q_list.number.circle_number ul>li:before { color: #fff; background-color: #1abc9c; border-radius: 2em; height: 31px; width: 31px; line-height: 31px; top: -3px; } .q_list.circle.animate_list ul li, .q_list.number.animate_list ul li{ opacity: 0; filter: alpha(opacity = 0); top: -40px; } .touch .no_animation_on_touch .q_list.circle.animate_list ul li, .touch .no_animation_on_touch .q_list.number.animate_list ul li{ opacity: 1; filter: alpha(opacity = 100); top: 0px; } /* ========================================================================== Social icon shortcode styles ========================================================================== */ .q_social_icon_holder{ display: inline-block; position: relative; } .q_social_icon_holder.normal_social{ margin: 0 6px; } header .header_top .q_social_icon_holder { float: left; margin: 0; width: 32px; } .q_social_icon_holder .simple_social { color: #bcbcbc; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; } .q_social_icon_holder span.simple_social { display: inline-block; } .q_social_icon_holder:hover .simple_social{ color: #1abc9c; } header .header_top .q_social_icon_holder a { display: block; } header .header_top .q_social_icon_holder:last-child { border-right: 0; } header .header_top .q_social_icon_holder .simple_social.fa-lg{ font-size: 13px; } .q_social_icon_holder .fa-stack { background-color: #e3e3e3; border: 0px solid #f0f0f0; margin: 0.2307692307692308em; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } .q_social_icon_holder.circle_social .fa-stack { -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; } .q_social_icon_holder .fa-stack .header_top .q_social_icon_holder .fa-stack { background: transparent; border: 0; padding: 0; margin: 0; box-shadow: none; border-radius: 0; font-size: 13px; } .header_top .q_social_icon_holder .fa-stack:hover i, .header_top .q_social_icon_holder .fa-stack:hover span { color: #fff; } .q_social_icon_holder .fa-stack i, .q_social_icon_holder .fa-stack span { color: #b9b9b9; -webkit-transition: color 0.3s ease-out; -moz-transition: color 0.3s ease-out; -o-transition: color 0.3s ease-out; transition: color 0.3s ease-out; } .header_top .q_social_icon_holder .fa-stack i, .header_top .q_social_icon_holder .fa-stack span{ color: #7b7b7b; } .q_social_icon_holder.circle_social .fa-stack:hover, .q_social_icon_holder.square_social .fa-stack:hover { background-color: #1abc9c; border-color: transparent; } .q_social_icon_holder.circle_social .fa-stack:hover i, .q_social_icon_holder.circle_social .fa-stack:hover span, .q_social_icon_holder.square_social .fa-stack:hover i, .q_social_icon_holder.square_social .fa-stack:hover span { color: #fff; } .q_social_icon_holder .fa-stack i.fa-circle, .q_social_icon_holder .fa-stack span.fa-circle { color: #fbfbfb; } .q_social_icon_holder .fa-stack.fa-2x { width:36px; height:36px; line-height:36px; } .q_social_icon_holder .fa-stack i:last-child, .q_social_icon_holder .fa-stack span { font-size: 0.7692307692307692em; display: block; line-height: inherit; } .q_social_icon_holder .fa-stack.fa-lg i:last-child, .q_social_icon_holder .fa-stack.fa-lg span { font-size: 1em; } /* ========================================================================== Social share shortcode styles ========================================================================== */ .social_share_holder{ position: relative; display: inline-block; } .social_share_holder:hover .social_share_title { cursor: pointer; } .social_share_holder:hover .social_share_dropdown{ visibility: visible; } .social_share_title{ display: inline-block; } .social_share_dropdown{ display: block; left: 3px; margin: 0px 0 0; padding: 10px 0 0 0; position: absolute; top: 100%; width: 35px; visibility: hidden; z-index: 950; } .social_share_dropdown .inner_arrow { display: block; position: absolute; top: -6px; left: 8px; width: 0; height: 0; border-color: transparent transparent #323232 transparent; border-style: solid; border-width: 9px; z-index: 999; } .social_share_dropdown ul { list-style: none; position: relative; display: block; background-color: #323232; z-index: 990; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; padding: 4px 0px !important; width:35px; } .page_share{ position: relative; } .social_share_dropdown ul li{ display: block; position: relative; text-align: center; } .social_share_dropdown ul li.share_title { display: block; text-align: center; color: #fff; background-color: #1abc9c; padding: 10px 20px; } .social_share_dropdown ul li a { display: block; height: 20px; line-height: 20px; padding: 5px 0; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; margin: 0 !important; } .social_share_dropdown ul li:last-child a { border-bottom: 0; } .social_share_dropdown ul li i{ font-size: 17px; width: 22px; height: 22px; line-height: 22px; color: #fff; text-align: center; } .social_share_dropdown ul li img{ width: 22px; float: left; margin: 0 13px 0 0; } .social_share_dropdown ul li :hover i{ color: #1abc9c; } /* ========================================================================== Social share list shortcode styles ========================================================================== */ .social_share_list_holder ul { list-style: none; display: inline-block; } .social_share_list_holder ul li { display: inline; margin-right: 10px; } .social_share_list_holder ul li i { color: #bcbcbc; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; } .social_share_list_holder ul li i:hover { color: #1abc9c; } /* ========================================================================== Empty Space ========================================================================== */ .vc_empty_space_inner .empty_space_image{ display: block; height: 100%; } /* ========================================================================== Masonry Gallery ========================================================================== */ .grid-sizer { width: 25%; } .masonry_gallery_holder{ margin: 0 -10px; opacity: 0; } .masonry_gallery_holder .masonry_gallery_item { box-sizing: border-box; padding: 10px; z-index: 1; } .masonry_gallery_holder .masonry_gallery_item.parallax_item { z-index: 0; } /*one column shortcode*/ .masonry_gallery_holder.one_column .masonry_gallery_item.square_big, .masonry_gallery_holder.one_column .masonry_gallery_item.square_small, .masonry_gallery_holder.one_column .masonry_gallery_item.rectangle_landscape, .masonry_gallery_holder.one_column .masonry_gallery_item.rectangle_portrait, .masonry_gallery_holder.one_column .grid-sizer{ width: 100%; } /*end of one column shortcode*/ /*two columns shortcode*/ .masonry_gallery_holder.two_columns .masonry_gallery_item.square_small, .masonry_gallery_holder.two_columns .masonry_gallery_item.rectangle_portrait, .masonry_gallery_holder.two_columns .grid-sizer{ width: 50%; } .masonry_gallery_holder.two_columns .masonry_gallery_item.square_big, .masonry_gallery_holder.two_columns .masonry_gallery_item.rectangle_landscape{ width: 100%; } /*end of two columns shortcode*/ /*three columns shortcode*/ .masonry_gallery_holder.three_columns .masonry_gallery_item.square_small, .masonry_gallery_holder.three_columns .masonry_gallery_item.rectangle_portrait, .masonry_gallery_holder.three_columns .grid-sizer{ width: 33.33333333%; } .masonry_gallery_holder.three_columns .masonry_gallery_item.square_big, .masonry_gallery_holder.three_columns .masonry_gallery_item.rectangle_landscape{ width: 66.66666666%; } /*end of three columns shortcode*/ .masonry_gallery_item.square_small { width: 25%; } .masonry_gallery_item.square_big { width: 50%; } .masonry_gallery_item.rectangle_landscape { width: 50%; } .masonry_gallery_item.rectangle_portrait { width: 25%; } .masonry_gallery_holder .masonry_gallery_item .masonry_gallery_image_holder{ height: 100%; width: 100%; position: relative; overflow: hidden; -webkit-transform: translateZ(0px); -moz-transform: translateZ(0px); -ms-transform: translateZ(0px); -o-transform: translateZ(0px); transform: translateZ(0px); } .masonry_gallery_holder .masonry_gallery_item.rectangle_landscape .masonry_gallery_image_holder img{ max-height: inherit; } .masonry_gallery_holder .masonry_gallery_item.rectangle_portrait .masonry_gallery_image_holder img{ max-width: inherit; width: auto; } .masonry_gallery_item img { position: absolute; top: 0; left: 0; height: 100%; width: 100%; vertical-align: middle; max-height: 100%; } .masonry_gallery_item .masonry_gallery_item_outer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; text-align: center; box-sizing: border-box; padding: 10px; } .masonry_gallery_item .masonry_gallery_item_inner { position: relative; height: 100%; } .masonry_gallery_item_inner .masonry_gallery_item_content { position: absolute; top: 50%; -webkit-transform: translateY(-50%); -ms-transform: translateY(-50%); -moz-transform: translateY(-50%); -o-transform: translateY(-50%); transform: translateY(-50%); width: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding:0 10% 0 10%; } .masonry_gallery_item.with_icon .masonry_gallery_item_inner, .masonry_gallery_item.with_button .masonry_gallery_item_inner{ background-color: rgba(0,0,0,0.8); } .masonry_gallery_item.standard .masonry_gallery_item_inner{ opacity: 0; background-color: rgba(0,0,0,0.8); -webkit-transition: opacity 0.3s ease-in-out; -moz-transition: opacity 0.3s ease-in-out; transition: opacity 0.3s ease-in-out; } .masonry_gallery_item.standard:hover .masonry_gallery_item_inner{ opacity: 1; } .masonry_gallery_item_content h3, .masonry_gallery_item_icon { color: #fff; } .masonry_gallery_item .masonry_gallery_item_icon { color: #fff; margin: 0 0 10px; } .masonry_gallery_item_content h3 { text-transform: uppercase; padding: 0 0 20px 0; } .masonry_gallery_item .masonry_gallery_item_button{ margin: 20px 0 0 0; } .masonry_gallery_item_content .masonry_gallery_item_text { color: #818181; } /* ========================================================================== Blog slider ========================================================================== */ .blog_slider, .blog_slides .image_holder { position: relative; display: block; -webkit-backface-visibility: hidden; } .blog_slider .blog_slides { opacity: 0; } .blog_slider .image{ position: relative; display: block; overflow: hidden; width: 100%; -moz-transform: translateZ(0px); -webkit-transform: translateZ(0px); } .blog_slider .blog_slides>li{ background-color: transparent; position: relative; margin: 0; float: left; } .blog_slider_holder .item_holder { position: relative; overflow: hidden; } .blog_slider { margin: 0; width: 100.2%; position: relative; zoom: 1; } .blog_slider .blog_slides img { width: 100%; display: block; -webkit-transition: -webkit-transform 0.15s ease-out; -moz-transition: -moz-transform 0.15s ease-out; -ms-transition: -ms-transform 0.15s ease-out; -o-transition: -o-transform 0.15s ease-out; transition: transform 0.15s ease-out; } .blog_slider .flex-viewport { max-height: 2000px; -webkit-transition: all 1s ease; -moz-transition: all 1s ease; transition: all 1s ease; direction: ltr; } .blog_slider .blog_slides { margin: 0; padding: 0; list-style: none; zoom: 1; } .blog_slider .flex-direction-nav{ *height: 0; } .blog_text_holder{ position:absolute; width:100%; height:100%; opacity: 0; -webkit-transition: all 1s ease; -moz-transition: all 1s ease; transition: all 1s ease; background-color: rgba(21, 21, 21, 0.78); } .blog_slides .blog_text_holder_inner{ color: #fff; } .blog_text_holder_outer{ display: table; table-layout: fixed; width: 100%; height: 100%; text-align: center; } .blog_text_holder_inner{ display: table-cell; vertical-align: middle; } .blog_slides .item:hover .blog_text_holder { opacity: 0.8; z-index: 20; } .blog_slides .blog_text_holder_inner .blog_slider_title a, .blog_slider_date_holder, .blog_slides .blog_text_holder_inner .blog_slider_categories a, .blog_slider .blog_slider_post_comments{ color: #fff; -webkit-transition: color 0.15s ease; -moz-transition: color 0.15s ease; transition: color 0.15s ease; } .blog_slider .blog_slider_date_holder, .blog_slider .blog_slider_categories{ display: inline-block; } .blog_slider .caroufredsel-next, .full_width .section_inner .blog_slider .caroufredsel-next{ right: 20px; } body.boxed .blog_slider .caroufredsel-next, body.boxed .full_width .section_inner .blog_slider .caroufredsel-next{ right: 0; } .blog_slider .caroufredsel-prev, .full_width .section_inner .blog_slider .caroufredsel-prev{ left: 20px; } body.boxed .blog_slider .caroufredsel-prev, body.boxed .full_width .section_inner .blog_slider .caroufredsel-prev{ left: 0; } .blog_slider .caroufredsel-next, .full_width .section_inner .blog_slider .caroufredsel-next, .blog_slider .caroufredsel-prev, .full_width .section_inner .blog_slider .caroufredsel-prev{ border-radius:50%; } .blog_slider .flex-container a:active, .blog_slider .flexslider a:active, .blog_slider .flex-container a:focus, .blog_slider .flexslider a:focus{ outline: 0; } /*Blog Carousel Info in Bottom Always*/ .blog_text_holder.info_bottom{ height: auto; width: auto; bottom: 0; margin: 0 10px 10px; opacity: 1; z-index: 20; } .blog_slides .item:hover .blog_text_holder.info_bottom{ opacity: 1; } .blog_text_holder.info_bottom .blog_text_holder_outer{ padding: 15px 0; } .blog_text_holder.info_bottom .blog_text_date_holder{ display: table-cell; vertical-align: middle; width: 60px; border-right: 1px solid #ebebeb; } .blog_text_holder.info_bottom .blog_text_holder_inner{ padding: 0 10px; text-align: left; } .blog_text_holder.info_bottom .blog_slider_date_holder span{ display: block; } /*Blog slider simple*/ .blog_slider_holder .blog_slider.simple_slider .blog_text_wrapper{ position: absolute; left: 0; top: 0; width: 100%; height: 100%; } .blog_slider.simple_slider .blog_slides .blog_text_holder_inner{ color: #303030; } .blog_slider_holder .blog_slider.simple_slider .blog_text_holder_inner2{ position: relative; width: 50%; margin: 0 auto; padding : 8%; border: 1px solid #fafafa; background-color: rgba(255,255,255,0.6); box-sizing: border-box; -webkit-transition: background-color 0.15s ease-out, border-color 0.15s ease-out; -moz-transition: background-color 0.15s ease-out, border-color 0.15s ease-out; -ms-transition: background-color 0.15s ease-out, border-color 0.15s ease-out; -o-transition: background-color 0.15s ease-out, border-color 0.15s ease-out; transition: background-color 0.15s ease-out, border-color 0.15s ease-out; } .blog_slider_simple_info{ text-align: center; } .blog_slider .blog_slider_simple_title{ margin-bottom: 20px; } .blog_slider .blog_slider_simple_info a, .blog_slider .blog_slider_simple_title a{ -webkit-transition: color 0.15s ease; -moz-transition: color 0.15s ease; transition: color 0.15s ease; } .blog_slider_simple_holder .read_more_wrapper{ margin-top: 20px; } .blog_slider_simple_info .post_info_item{ display: inline-block; padding: 0 5px; } .blog_slider_simple_info .post_info_item:not(:first-child):before{ content: '/'; position: relative; left: -5px; } .blog_slider_simple_info .post_info_item.date span{ -webkit-transition: color 0.15s ease-out; -moz-transition: color 0.15s ease-out; -ms-transition: color 0.15s ease-out; -o-transition: color 0.15s ease-out; transition: color 0.15s ease-out; } /* ========================================================================== Latest posts styles ========================================================================== */ .latest_post_holder{ display: inline-block; width: 100%; } .latest_post_holder.date_in_box .latest_post { padding-left:85px; } .latest_post_holder.minimal .latest_post{ border-bottom: none; padding-bottom: 0px; } .latest_post_holder li:last-child .latest_post { border-bottom: none; } .latest_post_holder .latest_post_date { float: left; margin-right: 25px; width: 59px; border-radius: 4px; text-align: center; margin-top: 5px; } .latest_post_holder .latest_post_date .post_publish_day { font-size: 22px; color: #fff; height: 39px; line-height: 39px; background-color: #1abc9c; } .latest_post_holder .latest_post_date .post_publish_month { border: 1px solid #eaeaea; background-color: #f4f4f4; color: #303030; font-size: 12px; -webkit-border-bottom-left-radius: 2px; -webkit-border-bottom-right-radius: 2px; -moz-border-radius-bottomleft: 2px; -moz-border-radius-bottomright: 2px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; height: 18px; line-height: 18px; } .latest_post_holder > ul{ list-style: none; display: inline-block; width: 100%; position: relative; margin: 0; padding:0; } .latest_post_holder > ul > li { display: block; position: relative; padding-top: 15px; } .latest_post_holder.minimal > ul > li { padding-top: 11px; } .latest_post_holder.image_in_box .latest_post_holder > ul > li{ padding-top: 15px; } .latest_post_holder > ul > li:first-child{ padding-top: 0; } .latest_post_holder.boxes > ul, .latest_post_holder.dividers > ul{ clear: both; } .latest_post_holder.boxes > ul > li, .latest_post_holder.dividers > ul > li{ padding: 0; float: left; border: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -o-box-sizing: border-box; margin: 0 2% 0 0; background-color:#fff; } .latest_post_holder.boxes.two_columns > ul > li, .latest_post_holder.dividers.two_columns > ul > li{ width: 49%; } .latest_post_holder.boxes.three_columns > ul > li, .latest_post_holder.dividers.three_columns > ul > li{ width: 32%; } .latest_post_holder.boxes.four_columns > ul > li, .latest_post_holder.dividers.four_columns > ul > li{ width: 23.5%; } .latest_post_holder.boxes.two_columns > ul > li:nth-child(2n), .latest_post_holder.boxes.three_columns > ul > li:nth-child(3n), .latest_post_holder.boxes.four_columns > ul > li:nth-child(4n), .latest_post_holder.dividers.two_columns > ul > li:nth-child(2n), .latest_post_holder.dividers.three_columns > ul > li:nth-child(3n), .latest_post_holder.dividers.four_columns > ul > li:nth-child(4n){ margin-right: 0; } .latest_post_holder.boxes:not(.one_row) > ul > li, .latest_post_holder.dividers:not(.one_row) > ul > li{ margin-bottom: 25px; } .latest_post_holder.boxes > ul > li .latest_post{ padding: 19px 20px 10px; border-top: 0; } .latest_post_holder.boxes > ul > li .latest_post p.excerpt{ margin: 10px 0 9px; } .latest_post_holder.boxes > ul > li .latest_post .post_infos > a, .latest_post_holder.boxes > ul > li .latest_post .post_infos > span{ display: inline-block; } .latest_post_holder.boxes > ul > li .latest_post .latest-vert-separator{ margin-left: 3px; } .latest_post_holder.boxes .boxes_image { overflow: hidden; } .latest_post_holder.boxes .boxes_image a { display: block; -webkit-transform: scale(1); -moz-transform: scale(1); -ms-transform: scale(1); -o-transform: scale(1); transform: scale(1); -webkit-transition: -webkit-transform 0.3s ease-in-out; -moz-transition: -moz-transform 0.3s ease-in-out; -ms-transition: -ms-transform 0.3s ease-in-out; -o-transition: -o-transform 0.3s ease-in-out; transition: transform 0.3s ease-in-out; -webkit-backface-visibility: hidden; } .latest_post_holder.boxes .boxes_image a img { vertical-align: top; } .latest_post_holder.boxes .boxes_image a:hover { -webkit-transform: scale(1.1); -moz-transform: scale(1.1); -ms-transform: scale(1.1); -o-transform: scale(1.1); transform: scale(1.1); } .latest_post_holder.dividers .latest_post_date, .latest_post_holder.dividers .latest_post_text_inner{ display: table-cell; } .latest_post_holder.dividers .latest_post_title{ margin-bottom: 20px } .latest_post_holder.dividers .latest_post_inner{ margin: 35px 0 !important; } .latest_post_holder.dividers .boxes_image img{ display: inline-block; vertical-align: middle; } .latest_post_holder.dividers .latest_post_date{ margin: 0 15px 0 0; border-right: 1px solid #ebebeb; width: 50px; } .latest_post_holder.dividers .latest_post_date .latest_post_day{ font-size: 15px; font-weight: 600; color: #303030; } .latest_post_holder.dividers .post_infos{ margin-top:30px; padding-top: 20px; border-top: 1px solid #ebebeb; } .latest_post_holder.dividers .post_infos > a:not(:last-child):after, .latest_post_holder.dividers .post_infos > span:not(:last-child) > a:after{ content: '/'; margin: 0 3px; } .latest_post_holder.dividers .latest_post_text_inner .post_infos a{ margin-right: 0; } .latest_post_holder > ul > li .date_hour_holder i{ margin-right: 8px; } .latest_post, .latest_post > a, .latest_post a img{ display: block; position: relative; } .latest_post_image { width: 95px; float: left; } .latest_post_image img{ width:100%; float: left; } .latest_post_text{ display: block; width: auto; } .latest_post_holder.image_in_box .latest_post_text{ padding:0 0 0 116px; } .latest_post_holder.minimal .latest_post_inner{ margin: 0 0 0px !important; } .latest_post_inner{ margin: 0 0 10px !important; } .latest_post_holder.image_in_box .latest_post_text_inner { display: table-cell; vertical-align: middle; } .latest_post_holder.image_in_box .latest_post_inner { display: table; width: 100%; margin: 0 0 0 !important; } .latest_post_inner .post_infos{ display: block; font-weight: 500; } .latest_post_inner .post_infos a{ color:#303030; } .latest_post_inner .post_infos a{ margin: 0 7px 0 0; } .latest_post_inner .post_infos a.post_comments{ margin: 0; } .latest_post_inner .post_infos a:hover{ color:#1abc9c; } .latest_post_holder.minimal .latest_post_inner .post_infos{ margin:0 0 3px 0; } .latest_post_holder.image_in_box .latest_post_text .latest_post_title { margin:-3px 0 2px 0; } .latest_post_holder.image_in_box .latest_post_text .excerpt { margin:0 0 8px 0; } .latest_post_holder .post_infos .dots{ padding: 0 7px 0 7px; } .latest_post_holder .post_infos .dots i{ font-size: 3px; vertical-align: middle; } /* ========================================================================== Blog Masonry Shortcode ========================================================================== */ .q_masonry_blog { margin-bottom: 50px; transition: none !important; overflow: visible !important; opacity: 0; filter: alpha(opacity=0); } .q_masonry_blog article, .full_width .grid_section .q_masonry_blog article { width: 31.2%; margin: 0 0 20px; padding: 0; text-align: left; vertical-align: top; z-index: 100; border: 0; background-color: #fff; float: left; display: block; } .full_width .q_masonry_blog article{ width: 18.9%; margin-left: 0.5%; margin-right: 0.5%; } .q_masonry_blog article.format-link:hover, .q_masonry_blog article.format-quote:hover{ background-color: #1abc9c; } .q_masonry_blog article.format-link .q_masonry_blog_post_title, .q_masonry_blog article.format-quote .q_masonry_blog_post_title{ padding: 0 0 0 60px; } .q_masonry_blog article.format-quote .q_masonry_blog_post_text i.qoute_mark, .q_masonry_blog article.format-link .q_masonry_blog_post_text i.link_mark { margin: 7px 0 0; color: #c0c0c0; font-size: 36px; } .q_masonry_blog article.format-quote .q_masonry_blog_post_text p, .q_masonry_blog article.format-link .q_masonry_blog_post_text p{ font-size: 21px; line-height: 35px; color: #303030; } .q_masonry_blog article.format-link:hover .q_masonry_blog_post_info, .q_masonry_blog article.format-link:hover .q_masonry_blog_post_info a, .q_masonry_blog article.format-quote:hover .q_masonry_blog_post_info, .q_masonry_blog article.format-quote:hover .q_masonry_blog_post_info a, .q_masonry_blog article.format-quote:hover .q_masonry_blog_post_text .quote_author, .q_masonry_blog article.format-quote:hover .q_masonry_blog_post_text i.qoute_mark, .q_masonry_blog article.format-link:hover .q_masonry_blog_post_text i.link_mark, .q_masonry_blog article.format-quote:hover .q_masonry_blog_post_text p a, .q_masonry_blog article.format-link:hover .q_masonry_blog_post_text p a { color: #fff; } .two_columns_75_25 .q_masonry_blog article, .two_columns_66_33 .q_masonry_blog article, .two_columns_33_66 .q_masonry_blog article, .two_columns_25_75 .q_masonry_blog article{ width:48%; } .q_masonry_blog article:hover{ z-index: 200; } .q_masonry_blog article .q_masonry_blog_post_image{ margin: 0; width: auto; } .q_masonry_blog article .q_masonry_blog_post_image img{ vertical-align: middle; } .q_masonry_blog article .q_masonry_blog_post_info{ margin:15px 0 0 0; color:#303030; } .q_masonry_blog article .q_masonry_blog_post_info a{ color: #bebebe; } .q_masonry_blog article .q_masonry_blog_post_info a:hover{ color: #1abc9c; } .q_masonry_blog article .quote_author { font-family: inherit; font-weight: 400; display: block; font-size: 21px; line-height: 35px; color: #c0c0c0; } .q_masonry_blog article.format-link .q_masonry_blog_post_info, .q_masonry_blog article.format-quote .q_masonry_blog_post_info{ margin: 0 0 20px; } .q_masonry_blog article .q_masonry_blog_post_text{ padding: 20px 15px 20px 15px; } .q_masonry_blog article h5{ margin:0 0 10px; } .q_masonry_blog article .mejs-controls div.mejs-horizontal-volume-slider{ margin: 0 10px 0 0; } .q_masonry_blog article .flexslider{ margin-bottom: 0; } /* ========================================================================== Blog ========================================================================== */ .blog_holder article{ display: inline-block; width: 100%; margin: 0 0 60px; } .blog_holder.masonry article, .blog_holder.masonry_full_width article { display: block; float: left; } .blog_holder.blog_large_image_simple article{ margin: 0 0 23px; } .blog_holder.blog_single article{ margin: 0 0 0px; } .blog_holder.blog_small_image article{ margin: 0 0 32px; } .single-post .blog_single p { margin-bottom: 22px; } .single-post .blog_single p:last-child { margin-bottom: 0; } .blog_single.blog_holder article .post_text .post_text_inner{ padding-left:0; padding-right:0; padding-bottom:0; background-color:transparent; } .blog_single.blog_holder article.format-link .post_text .post_text_inner, .blog_single.blog_holder article.format-quote .post_text .post_text_inner{ padding: 23px 23px 35px 23px; background-color: #fff; margin:0 0 30px 0; } .blog_holder article .post_content_holder{ width: 100%; } .blog_holder article .post_image, .blog_holder article .post_image > a, .blog_holder article .post_image img{ position: relative; width: 100%; display: block; } .blog_holder article .post_text .post_text_inner{ padding:23px 23px 35px 23px; background-color:#fff; } .blog_holder.blog_large_image_simple article .post_text .post_text_inner{ background-color: transparent; padding-left: 195px; padding-right: 195px; padding-top: 45px; padding-bottom: 45px; text-align: center; } .blog_holder.masonry article .post_text .post_text_inner, .blog_holder.masonry_full_width article .post_text .post_text_inner{ padding:17px 15px 18px 15px; background-color:#fff; } .blog_large_image_simple .minimalist_date{ padding-bottom: 9px; color:#1abc9c; } .blog_large_image_simple .separator.small{ margin-top: 22px; } .blog_holder article .post_text h5 { margin:0 0 10px; } .blog_holder article .post_text h2 .date{ color:#bebebe; } .blog_holder article .post_info { display:inline-block; width:100%; margin:0 0 18px; color:#bebebe; font-weight:500; } .blog_holder article .post_info a{ color:#bebebe; } .blog_holder article .post_info a:hover{ color:#1abc9c; } .blog_holder article.format-quote .post_info, .blog_holder article.format-link .post_info { margin:0 0 15px; } .blog_holder article .post_info .dots{ padding: 0 7px 0 4px; } .blog_holder article .post_info .dots i{ font-size: 3px; vertical-align: middle; } .blog_holder article .post_more{ margin:30px 0 0; } .blog_holder article .video .mobile-video-image { background-position: center center; background-repeat: no-repeat; background-size: cover; display: none; height: 100%; left: 0; position: absolute; top: 0; width: 100%; z-index: 10; } .blog_holder article .video{ position: relative; } .blog_holder article .video .video-wrap { overflow: hidden; position: relative; width: 100%; z-index: 10; } .blog_holder article .video .video-wrap .mejs-poster { background-size: cover!important; -moz-background-size: cover!important; -webkit-background-size: cover!important; -o-background-size: cover!important; width: 100% !important; height: 100% !important; } .blog_holder article .video .video-wrap .mejs-container { background-color: transparent!important; background-image: none!important; height: 100% !important; width: 100% !important; overflow: hidden; } .blog_holder article .video .video-wrap .mejs-mediaelement{ background: none !important; border: 0px !important; } .blog_holder article .video .video-wrap .mejs-container .mejs-poster img { max-width: none!important; width: 100%!important; } .blog_holder article .mejs-container .mejs-controls{ visibility: visible !important; } .blog_holder article .mejs-controls .mejs-volume-button .mejs-volume-slider{ display: none !important; } .blog_holder article .post_image .mejs-poster img{ display: none !important; } .blog_holder article.format-gallery .flexslider{ margin: 0px; overflow: hidden; } .portfolio_single .flexslider{ overflow: hidden; } .blog_holder.blog_small_image article .post_image, .blog_holder.blog_small_image article .post_text{ width:50%; float:left; margin:0; } .blog_holder.blog_small_image article .post_text .post_text_inner{ padding: 23px 23px 23px 23px; } .grid2 .blog_holder.blog_small_image article .post_comments { margin-left: 0; } .blog_holder article .post_description{ margin: 2px 0 10px; } /*Blog Large Image With Dividers*/ .blog_holder.blog_large_image_with_dividers .post_text_holder{ display: table; width: 100%; height: 100%; } .blog_holder.blog_large_image_with_dividers article .post_text .post_text_inner{ padding: 35px 0; } .blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column1{ display: table-cell; vertical-align: top; text-align: center; width: 70px; } .blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column2{ display: table-cell; padding: 0 35px 0 20px; } .blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column2 > h2{ margin-bottom: 20px; } .blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column1 .date{ padding: 0 20px; border-right: 1px solid #ebebeb; } .blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column1 .date > span{ display: block; } .blog_holder.blog_large_image_with_dividers .post_text_holder .blog_column1 .date_day{ font-size: 21px; font-weight: 600; color: #303030; padding-bottom: 5px; } .blog_holder.blog_large_image_with_dividers article .post_info{ display: table; width: 100%; border-top: 1px solid #ebebeb; padding-top: 15px; color: #303030; margin-bottom: 0; } .blog_holder.blog_large_image_with_dividers article:not(.format-quote):not(.format-link) .post_info{ margin-top: 30px; } .blog_holder.blog_large_image_with_dividers article .post_info .post_info_left{ display: table-cell; } .blog_holder.blog_large_image_with_dividers article .post_info .post_info_right{ display: table-cell; text-align: right; } .blog_holder.blog_large_image_with_dividers article .post_info a{ display: inline-block; color: #303030; } .blog_holder.blog_large_image_with_dividers article .post_info a:hover{ color: #1abc9c; } .blog_holder.blog_large_image_with_dividers article .post_info .post_info_right > a:not(:first-child):before, .blog_holder.blog_large_image_with_dividers article .post_info .post_info_right > div:not(:first-child):before{ content: '/ '; } .blog_holder.blog_large_image_with_dividers article.format-quote .post_text .post_title, .blog_holder.blog_large_image_with_dividers article.format-link .post_text .post_title{ padding: 0; } .blog_holder.blog_large_image_with_dividers article.format-link .post_text .post_title a{ color: #1abc9c; text-decoration: underline; } .blog_holder.blog_large_image_with_dividers article.format-link .post_text:hover .post_title a{ color: #fff; } .blog_holder.blog_large_image_with_dividers article.format-quote .post_text .quote_author{ margin-top:30px; color: #1abc9c; } .blog_holder.blog_large_image_with_dividers article.format-quote .post_info, .blog_holder.blog_large_image_with_dividers article.format-link .post_info{ margin-top: 20px; } .blog_holder.blog_large_image_with_dividers article.format-quote .post_text span.qoute_mark, .blog_holder.blog_large_image_with_dividers article.format-link .post_text span.link_mark{ font-size: 28px; padding: 0 18px; border-right: 1px solid #ebebeb; color: #303030; } .latest_post_inner .post_comments i { font-size:16px; color: #adadad; padding:0 8px 0 0; } .latest_post_inner .post_comments:hover i { color:#1abc9c; } .blog_holder article .post_info .post_info_left a.post_author_avatar { display:inline-block; float:left; padding:0 10px 0 0; } .blog_holder article .post_info .post_info_left a.post_author { display:inline-block; line-height:64px; float:left; } .post_author_avatar img{ border-radius:60px; border:2px solid #eaeaea; } .blog_holder.masonry article .post_description, .blog_holder.masonry_full_width article .post_description{ margin:0 0 4px; } .blog_holder article .post_description a:hover, .blog_holder article .post_description .post_comments:hover{ color: #1abc9c; } .blog_like{ display: inline-block; } .blog_like a{ display: block; line-height: 14px; } .blog_like a i{ color: #adadad; font-size: 16px; } .blog_holder.masonry article .blog_like a i, .blog_holder.masonry_full_width article .blog_like a i, .blog_holder.blog_single article .blog_like a i, .blog_holder.blog_large_image article .blog_like a i{ display: inline-block; } .blog_like a:hover i, .blog_like a.liked i, .blog_like a:hover span{ color: #1abc9c; } .blog_like span{ padding: 0 0 0 4px; } .blog_holder.masonry article .blog_like span, .blog_holder.masonry_full_width article .blog_like span, .blog_holder.blog_single article .blog_like span, .blog_holder.blog_large_image article .blog_like span{ display: inline-block; padding:0 0 0 5px; } .blog_holder article .post_info .qbutton.dark { text-transform: none; } .blog_share{ display: inline-block; } .blog_holder article.format-quote .post_text i.qoute_mark, .blog_holder article.format-link .post_text i.link_mark{ margin: 7px 0 0; color:#c0c0c0; font-size: 36px; } .blog_large_image_simple.blog_holder article.format-quote .post_text i.qoute_mark, .blog_large_image_simple.blog_holder article.format-link .post_text i.link_mark{ margin: 20px 0; float: none; } .blog_holder article.format-quote .post_text .post_title, .blog_holder article.format-link .post_text .post_title{ padding: 0 0 0 60px; } .blog_large_image_simple.blog_holder article.format-quote .post_text .post_title, .blog_large_image_simple.blog_holder article.format-link .post_text .post_title{ padding: 0 0 0 0px; } .blog_holder article.format-quote .post_text .post_title p, .blog_holder article.format-link .post_text .post_title p{ font-size:21px; line-height:35px; color:#303030; } .blog_holder article.format-quote .post_text .quote_author{ font-family: inherit; font-weight: 400; display:block; font-size: 21px; line-height: 35px; color:#c0c0c0; } .blog_holder article.format-link .post_text:hover .post_text_inner, .blog_holder article.format-quote .post_text:hover .post_text_inner { background-color: #1abc9c !important; /* it should be important so it can override default color from options */ } .blog_holder article.format-link .post_text:hover .post_text_inner, .blog_holder article.format-quote .post_text:hover .post_text_inner { border-color: #1abc9c !important; /* it should be important so it can override default color from options */ } .blog_holder article.format-link .post_text:hover .post_info, .blog_holder article.format-link .post_text:hover .post_info a, .blog_holder article.format-quote .post_text:hover .post_info, .blog_holder article.format-quote .post_text:hover .post_info a, .blog_holder article.format-quote .blog_like a:hover span, .blog_holder article.format-quote .post_text:hover .quote_author, .blog_holder article.format-quote .post_text:hover i.qoute_mark, .blog_holder article.format-link .post_text:hover i.link_mark, .blog_holder.blog_large_image_with_dividers article.format-quote .post_text:hover span.qoute_mark, .blog_holder.blog_large_image_with_dividers article.format-link .post_text:hover span.link_mark, .blog_holder.blog_large_image_with_dividers article.format-quote .post_text:hover .quote_author, .blog_holder article.format-link .blog_like a:hover span, .blog_holder article.format-quote .post_text:hover p a, .blog_holder article.format-link .post_text:hover p a, .blog_holder.blog_single article.format-quote .post_text:hover p, .blog_holder.blog_single article.format-link .post_text:hover p, .blog_large_image_simple article.format-quote .post_text:hover .minimalist_date, .blog_large_image_simple article.format-link .post_text:hover .minimalist_date, .blog_holder.masonry article.format-link .post_text:hover .post_info, .blog_holder.masonry article.format-link .post_text:hover .post_info a, .blog_holder.masonry article.format-quote .post_text:hover .post_info, .blog_holder.masonry article.format-quote .post_text:hover .post_info a, .blog_holder.masonry_full_width article.format-link .post_text:hover .post_info, .blog_holder.masonry_full_width article.format-link .post_text:hover .post_info a, .blog_holder.masonry_full_width article.format-quote .post_text:hover .post_info, .blog_holder.masonry_full_width article.format-quote .post_text:hover .post_info a { color:#fff; } .blog_holder.blog_single article h2{ display: block; } .blog_load_more_button_holder { text-align: center; padding:0 0 40px; } .blog_load_more_button_loading { display: none; } .single_links_pages{ margin: 50px 0 0; display: block; text-align:center; display: block; text-decoration: none; } .single_links_pages span{ position: relative; display: inline-block; width: 38px; height: 38px; line-height: 38px; margin: 0 11px 0 0; text-align: center; color: #303030; text-decoration: none; text-transform: uppercase; cursor: pointer; white-space: nowrap; border: 2px solid #e3e3e3; background-color: #e3e3e3; outline: none; -o-border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; text-shadow: none; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; } .single_links_pages a span { color: #b4b4b4; background-color:transparent; border-color: #e5e5e5; } .single_links_pages a:hover span{ background-color: #e3e3e3; border-color: #e3e3e3; color: #303030; } .author_description{ display: block; position: relative; margin: 34px 0 0; background-color:#fff; padding:23px 23px; } .author_description_inner{ display: block; } .author_description_inner .image{ display: block; width: 75px; height: 75px; float: left; border-radius: 75px; overflow:hidden; } .author_text_holder { padding: 0 0 0 100px; min-height: 100px; position:relative; } .author_text_holder .author_name { display: block; margin: 0px 0 4px 0; } .author_text_holder .author_email{ display:block; margin: 0px 0 6px 0; } .single_tags { margin:26px 0px 0px 0px; } .single_tags a, .widget .tagcloud a { letter-spacing:1px; } .single_tags h5{ display:inline-block; } .widget .tagcloud a { display: inline-block; font-size: 13px !important; } .widget .tagcloud a:after{ content:","; } .widget .tagcloud a:last-child:after{ content:""; } .blog_social_and_comments{ display: inline-block; width: 100%; margin: 0 0 20px; } .comment_number_holder{ display: inline-block; float: left; } .blog_single_social{ display: inline-block; float: right; } .blog_single_social .blog_like{ float: right; margin: 0 0 0 15px; } .comment_holder{ padding: 28px 0 38px; margin: 0 0 0; } .comment_number_holder .comment_number{ color: #000; } .comment_holder .comment_number{ margin:0 0 20px; } .comment_number .comment_number_inner i{ position: relative; top: -1px; padding:0 10px 0 0; } .comment_holder ul.comment-list{ list-style: none; position: relative; z-index: 150; padding:0; } .comment_holder .comment-list{ margin: 0; } .comment_holder .comment-list li{ display: inline-block; position: relative; width: 100%; } .comment_holder .comment-list li ul.children li:last-child{ padding:0 0 0px; } .comment_holder .comment-list > li{ margin: 0 0 18px; } .comment_holder .comment-list > li:last-child{ margin: 0; } .comment_holder .comment{ padding: 23px; background-color:#fff; } .comment_holder .comment .image { display: block; width: 75px; height: 75px; float: left; border-radius: 75px; overflow: hidden; } .comment_holder .comment .text { padding: 0 0 0 100px; min-height: 80px; position:relative; } .comment_holder .comment .text .name { display: block; color: #303030; } .comment_holder .comment .text .replay, .comment_holder .comment .text .comment-reply-link { color: #1abc9c; font-size:9px; text-transform:uppercase; font-weight:700; padding:0 0 0 5px; } .comment_holder .comment .text .text_holder { display: block; margin:3px 0 0 0; } .comment_holder .comment .logged-in-as { margin: 10px 0; } .comment_holder .comment .form-submit { margin: 0 0 20px; } .comment_holder .comment-list li ul.children { margin: 18px 0 0 0; padding: 0 0 0 70px; } .comment_holder .comment-list li ul.children li{ margin: 0px; border-bottom:none; } #respond h3 { margin: 0 0 15px 0; } #respond h3.comment-reply-title{ margin:0; } #respond small { display: block; margin: 0 0 12px; position: relative; } .comment_holder .comment .comment-respond{ margin-top: 20px; } #respond textarea, #respond input[type='text'], .contact_form input[type='text'], .contact_form textarea { width:100%; margin: 0 0 20px 0; padding: 15px 12px; border: 0; outline: 0; resize: none; font-size: 13px; line-height:17px; background-color:#fff; color: #818181; font-family: 'Raleway'; font-weight:400; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } #respond textarea { padding: 12px; } .comment_holder #respond textarea, .comment_holder #respond input[type='text']{ background-color: #fff; } .comment_holder .comment #respond textarea, .comment_holder .comment #respond input[type='text']{ background-color: #f6f6f6; } .comment_holder #respond textarea { margin: 0 0 12px; } div.comment_form { display: inline-block; margin: 0 0 30px; width: 100%; } div.comment_form form p.form-submit, div.comment_holder .comment p.form-submit { margin: 0; text-align: right; } div.comment_form form p.form-submit .success p{ margin: 10px 0 0; } div.comment_form form p.logged-in-as{ margin: 0 0 17px; } #cancel-comment-reply-link { margin: 0px; display: inline-block; width: 100%; } body.page-template-blog-masonry-full-width-php .content .full_width { padding: 0 20px 25px 45px; } body.page-template-blog-masonry-full-width-php.vertical_menu_enabled .content .full_width{ padding-left:305px; } .blog_holder.masonry, .blog_holder.masonry_full_width { margin-bottom: 20px; transition: none !important; overflow: visible !important; opacity: 0; filter: alpha(opacity=0); } #infscr-loading{ position: absolute; bottom:-15px; left: 50%; } .blog_infinite_scroll_button{ display: none; } .blog_holder.masonry article, .blog_holder.masonry_full_width article{ margin: 0 0 30px; padding: 0; text-align: left; vertical-align: top; z-index: 100; border: 0; } .blog_holder.masonry article, .blog_holder.masonry .blog_holder_grid_sizer{ width: 31.2%; } .blog_holder.masonry .blog_holder_grid_gutter{ width: 3.2%; } .blog_holder.masonry_full_width .blog_holder_grid_sizer, .blog_holder.masonry_full_width article{ width: 18.7%; } .blog_holder.masonry_full_width .blog_holder_grid_gutter{ width: 1.6%; } .two_columns_75_25 .blog_holder.masonry article, .two_columns_75_25 .blog_holder.masonry .blog_holder_grid_sizer, .two_columns_66_33 .blog_holder.masonry article, .two_columns_66_33 .blog_holder.masonry .blog_holder_grid_sizer, .two_columns_33_66 .blog_holder.masonry article, .two_columns_33_66 .blog_holder.masonry .blog_holder_grid_sizer, .two_columns_25_75 .blog_holder.masonry article, .two_columns_25_75 .blog_holder.masonry .blog_holder_grid_sizer{ width:48%; } .two_columns_75_25 .blog_holder.masonry .blog_holder_grid_gutter, .two_columns_66_33 .blog_holder.masonry .blog_holder_grid_gutter, .two_columns_33_66 .blog_holder.masonry .blog_holder_grid_gutter, .two_columns_25_75 .blog_holder.masonry .blog_holder_grid_gutter{ width: 4%; } .blog_holder.masonry article:hover{ z-index: 200; } .blog_holder.masonry article .post_image{ margin: 0; width: auto; } .blog_holder.masonry article .post_info, .blog_holder.masonry_full_width article .post_info{ margin:15px 0 0 0; color:#303030; } .blog_holder.masonry article.format-link .post_info, .blog_holder.masonry_full_width article.format-link .post_info, .blog_holder.masonry_full_width article.format-quote .post_info, .blog_holder.masonry article.format-quote .post_info{ margin: 0 0 20px; } .blog_holder.masonry article .post_text .post_text_innet, .blog_holder.masonry_full_width article .post_text .post_text_innet{ padding: 20px 15px 20px 15px; } .blog_holder.masonry article.format-link .post_text, .blog_holder.masonry_full_width article.format-link .post_text, .blog_holder.masonry article.format-quote .post_text, .blog_holder.masonry_full_width article.format-quote .post_text{ border:none; } .blog_holder article.format-quote h3{ margin:0 0 10px; line-height:35px; } .blog_holder.masonry article h4, .blog_holder.masonry_full_width article h4{ margin:0 0 4px; } .blog_holder.masonry article h3 a{ font-weight: 300; } .blog_holder.masonry article.format-link .post_text, .blog_holder.masonry_full_width article.format-link .post_text, .blog_holder.masonry_full_width article.format-quote .post_text, .blog_holder.masonry article.format-quote .post_text{ padding: 0; } .blog_holder.masonry article .mejs-controls div.mejs-horizontal-volume-slider, .blog_holder.masonry_full_width article .mejs-controls div.mejs-horizontal-volume-slider{ margin: 0 10px 0 0; } .blog_holder.blog_masonry_date_in_image .time{ position: absolute; top: 0; left: 0; text-align: center; margin: 5px; padding: 5px 13px; background-color: #fff; } .blog_holder.blog_masonry_date_in_image .time span{ display: block; } .blog_holder.blog_masonry_date_in_image .time .time_day{ color: #303030; font-size: 19px; font-weight: 600; } .blog_holder.blog_masonry_date_in_image article .post_text .post_text_inner{ text-align: center; padding: 35px 5px; } .blog_holder.blog_masonry_date_in_image article.format-quote .post_text .post_text_inner, .blog_holder.blog_masonry_date_in_image article.format-link .post_text .post_text_inner{ padding: 35px 15px; } .blog_holder.blog_masonry_date_in_image article .post_text h5{ margin-bottom: 30px; } .blog_holder.blog_masonry_date_in_image .post_text_inner .social_share_list_holder > span{ display: none; } .blog_holder.blog_masonry_date_in_image article .post_text_inner .post_info{ margin-top: 35px; margin-bottom: 0; } .blog_holder.blog_masonry_date_in_image .social_share_list_holder ul li i{ color: #8d8d8d; -webkit-transition: color 0s ease-in-out; -moz-transition: color 0s ease-in-out; -ms-transition: color 0s ease-in-out; -o-transition: color 0s ease-in-out; transition: color 0s ease-in-out; } .blog_holder.blog_masonry_date_in_image article:not(.format-quote):not(.format-link) .social_share_list_holder ul li i:hover{ color: #1abc9c; } .blog_holder.blog_masonry_date_in_image article.format-quote .post_text:hover .social_share_list_holder ul li i, .blog_holder.blog_masonry_date_in_image article.format-link .post_text:hover .social_share_list_holder ul li i{ color: #fff !important; } .isotope-item { z-index: 2; } .isotope-hidden.isotope-item { pointer-events: none; z-index: 1; } /**** Isotope CSS3 transitions ****/ /*.isotope, .isotope .isotope-item { -webkit-transition-duration: 0.8s; -moz-transition-duration: 0.8s; -ms-transition-duration: 0.8s; -o-transition-duration: 0.8s; transition-duration: 0.8s; }*/ .isotope { -webkit-transition-property: height; -moz-transition-property: height; -ms-transition-property: height; -o-transition-property: height; transition-property: height; } .isotope .isotope-item { -webkit-transition-property: -webkit-transform, opacity; -moz-transition-property: -moz-transform, opacity; -ms-transition-property: -ms-transform, opacity; -o-transition-property: -o-transform, opacity; transition-property: transform, opacity; } .isotope.no-transition, .isotope.no-transition .isotope-item, .isotope .isotope-item.no-transition { -webkit-transition-duration: 0s; -moz-transition-duration: 0s; -ms-transition-duration: 0s; -o-transition-duration: 0s; transition-duration: 0s; } /*************************** BLOG END **************************/ /* ========================================================================== Pagination styles ========================================================================== */ .pagination { display: inline-block; width: 100%; text-align: center; margin: 0px 0px 50px; position:relative; } .pagination ul { display: inline-block; list-style-type: none; margin: 0px; padding: 0px; } .pagination ul li { float: left; } .pagination ul li span, .pagination ul li a{ position: relative; display: inline-block; width: 38px; height: 38px; line-height: 38px; margin: 0 11px 0 0; text-align:center; color: #b4b4b4; font-size: 18px; text-decoration: none; text-transform: uppercase; cursor: pointer; white-space: nowrap; border: 2px solid #e5e5e5; outline: none; -o-border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; text-shadow: none; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; } .pagination ul li span, .pagination ul li a:hover{ color: #303030; background-color: #e3e3e3; border-color: #e3e3e3; } /* ========================================================================== End of Pagination styles ========================================================================== */ .google_map_holder, .google_map_shortcode_holder { position: relative; } .google_map_ovrlay { position: absolute; z-index: 1000; width: 100%; height: 100%; display: none; } .google_map_shortcode_overlay{ position: absolute; z-index: 1000; width: 100%; height: 100%; display: none; top:0; left:0; } .google_map { display: block; width: 100%; height: 450px; margin:0 0 25px; } .qode_google_map { display: block; width: 100%; height: 450px; } .google_map iframe, .google_map object, .google_map embed, .qode_google_map iframe, .qode_google_map object, .qode_google_map embed { width: 100%; display: block; } .google_map img, .qode_google_map img { max-width: none; } .contact_form h5{ margin:0 0 18px; } .contact_info .q_social_icon_holder .fa-stack { margin:0.2307692307692308em 0.4615384615384616em 0.2307692307692308em 0; } .contact-error{ display: block; margin: 0; position: relative; top: -20px; } .contact_section{ text-align:center; padding:0 0 55px; } .contact_section.contact_section_position_left{ text-align: left; } .contact_section.contact_section_position_right{ text-align: right; } .contact_section .separator, .contact_section .separator.small.right, .contact_section .separator.small.left { margin-top:6px; margin-bottom:35px; } span.submit_button_contact { display: block; text-align: right; } .contact_form { margin:0 0 50px; } .contact_detail.map_grid .google_map{ margin:0 0 35px; } .header-widget.widget_nav_menu { padding:0 15px 0 0; position:relative; font-size:12px; } .header-widget.widget_nav_menu ul ul { display:none; height: auto; border-top: none; background-color: #262626; z-index: 1010; position: absolute; top: 33px; left: -1px; width: 180px; padding:0px; } .header-widget.widget_nav_menu ul li:hover ul{ display:block; } .header-widget.widget_nav_menu ul li{ list-style:none; } .header-widget.widget_nav_menu ul.menu > li { display: inline-block; float:left; position:relative; } .header-widget.widget_nav_menu ul.menu li a{ display: inline-block; padding:0 0px 0 15px; color:#777; } .header-widget.widget_nav_menu ul.menu > li.menu-item-has-children > a:after { content: "\f107"; font-family: 'FontAwesome', sans-serif; margin-left: 5px; } .header-widget.widget_nav_menu ul.menu li a:hover{ color:#1abc9c; } .header-widget.widget_nav_menu ul.menu li ul li a{ color: #9d9d9d; display: block; white-space: nowrap; font-size: 11px; font-weight: 600; line-height: 38px; padding: 0 15px; border-bottom: 1px solid #303030; text-transform: uppercase; } .header-widget.widget_nav_menu ul.menu li ul li:last-child a{ border-bottom:0; } .header-widget ul.menu li:last-child { margin-right: 0; } .header-left-from-logo-widget, .header-right-from-logo-widget{ display: block; height: 100%; position: absolute; top: 0px; left: 0px; padding: 0px 50px; } .header-right-from-logo-widget{ left: auto; right: 0px; } header .container_inner .header-left-from-logo-widget, header .container_inner .header-right-from-logo-widget{ padding: 0px; } .header-left-from-logo-widget-inner, .header-right-from-logo-widget-inner{ display: table; height: 100%; } .header-left-from-logo-widget-inner2, .header-right-from-logo-widget-inner2{ display: table-cell; height: 100%; vertical-align: middle; } header.sticky .header-left-from-logo-widget, header.sticky .header-right-from-logo-widget{ display: none; } /* ========================================================================== Sidebar and side menu styles ========================================================================== */ /** * Common sidebar, side menu and widgets styles that are placed in this widget areas */ .container aside { position: relative; z-index: 11; } aside .widget a, .side_menu a, .side_menu .widget li { font-weight: 400; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; } aside .widget a:hover{ color: #1abc9c; } .side_menu .widget a:hover, .side_menu .widget li:hover, .side_menu .widget li:hover > a { color: #fff; } aside .widget ul, .side_menu .widget ul{ list-style: none; padding:0; } aside .widget li, .side_menu .widget li{ margin: 0 0 10px; } aside .widget li:last-child, .side_menu .widget li:last-child{ margin: 0; } .widget.widget_rss li a.rsswidget, #wp-calendar caption{ color: #000; } .footer_top .widget.widget_rss li a.rsswidget, .footer_top #wp-calendar caption{ color: #fff; } #wp-calendar th, #wp-calendar td{ padding: 3px 4px; } #wp-calendar td#today { color: #fff; background-color: #1abc9c; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; } #wp-calendar{ width: 100%; text-align: center; } .widget.widget_rss li span.rss-date, #wp-calendar caption{ margin: 0 0 15px; } .widget.widget_rss li{ margin: 0 0 25px; } /* Sidebar styles ========================================================================== */ /** * Sidebar specific styles */ aside .widget.widget_search{ border-bottom: 0px; padding: 0; } aside .widget h5 { margin-bottom: 14px; } aside .widget.posts_holder li { padding: 7px 0px 7px 0px; margin: 0; } aside .widget.posts_holder li.page_item_has_children > ul.children li:last-child, aside .widget.posts_holder li.menu-item-has-children > ul.sub-menu li:last-child{ border-bottom: 0; } aside .widget.posts_holder li:hover{ color: #1abc9c; } aside .widget.posts_holder li.page_item_has_children > ul.children, aside .widget.posts_holder li.menu-item-has-children > ul.sub-menu { padding-left: 10px; } aside .widget.posts_holder li.page_item_has_children > a, aside .widget.posts_holder li.menu-item-has-children > a { display: block; } aside .widget a { color: inherit; } aside .widget{ margin: 0 0 42px; } aside .widget_nav_menu .sub-menu, aside .widget_pages .children { margin-left: 20px; margin-top: 6px; } /* Side menu styles ========================================================================== */ /** * Side menu specific styles */ .side_menu{ background-color: #1b1b1b; height: 100%; min-height: 100%; overflow: hidden; padding: 30px; position: fixed; top: 0; right: -270px; width: 270px; z-index: 90; visibility: hidden; -webkit-backface-visibility: hidden; box-sizing:border-box; } /* Side Menu Slides Over Content */ .right_side_menu_opened .wrapper, .right_side_menu_opened footer.uncover{ left:-270px; } .side_menu_slide_from_right .wrapper{ background-color: #fff; position: relative; z-index: 1000; -moz-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); -o-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); -webkit-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); -ms-transform:translateX(0,0); -moz-transform:translateX(0,0); -o-transform:translateX(0,0); transform:translateX(0,0); -webkit-transform:translateX(0,0); } .side_menu_slide_from_right.right_side_menu_opened .wrapper{ transform:translateX(-270px,0); -ms-transform:translateX(-270px,0); -moz-transform:translateX(-270px,0); -webkit-transform:translateX(-270px,0); -o-transform:translateX(-270px,0); -moz-transition:left 0.2s cubic-bezier(.645,.045,.355,1.000); -o-transition:left 0.2s cubic-bezier(.645,.045,.355,1.000); -webkit-transition:left 0.2s cubic-bezier(.645,.045,.355,1.000); transition:left 0.2s cubic-bezier(.645,.045,.355,1.000); } .side_menu_slide_from_right .carousel-inner { -moz-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); -o-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); -webkit-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); } .side_menu_slide_from_right .wrapper .cover{ z-index: 0; position: fixed; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; opacity: 0; filter: alpha(opacity=0); background:#000; -moz-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; -o-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; -webkit-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; } .side_menu_slide_from_right.right_side_menu_opened .wrapper .cover{ z-index: 1002; opacity: 0.6; filter: alpha(opacity=60); -moz-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; -o-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; -webkit-transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; transition: opacity 0.2s ease-in-out,background 0.2s ease-in-out,z-index 0.2s ease-in-out; } .side_menu_slide_from_right .side_menu { padding: 5% 30px 30px 30px; top: 0; right: -45%; width: 45%; z-index: 9999; text-align: center; visibility: hidden; -moz-transition: 0.2s ease-in-out; -o-transition: 0.2s ease-in-out; -webkit-transition: 0.2s ease-in-out; transition: 0.2s ease-in-out; -webkit-box-sizing:border-box; box-sizing: border-box; } .right_side_menu_opened.side_menu_slide_from_right .side_menu { right: 0px; visibility: visible; -moz-transition: right 0.2s ease-in-out; -o-transition: right 0.2s ease-in-out; -webkit-transition: right 0.2s ease-in-out; transition: right 0.2s ease-in-out; } .side_menu_slide_from_right header.sticky, .side_menu_slide_from_right header.fixed_top_header .top_header, .side_menu_slide_from_right header.fixed, .side_menu_slide_from_right header.fixed_hiding, .side_menu_slide_from_right header.fixed_top_header .top_header{ -moz-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000), top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -o-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000), top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -webkit-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000), top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); transition: left 0.2s cubic-bezier(.645,.045,.355,1.000), top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); } .side_menu_slide_from_right footer.uncover { -moz-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); -o-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); -webkit-transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); transition: left 0.2s cubic-bezier(.645,.045,.355,1.000); } /* Side Menu Slides With Content */ body.side_menu_slide_with_content{ overflow-x: hidden; position: relative; left: 0; -webkit-overflow-scrolling:auto !important; } body.side_menu_slide_with_content.side_menu_open .wrapper, body.side_menu_slide_with_content.side_menu_open footer.uncover{ left: -470px; } body.side_menu_slide_with_content .wrapper{ -webkit-transition: left 0.2s ease, right 0.2s ease; -moz-transition: left 0.2s ease, right 0.2s ease; transition: left 0.2s ease, right 0.2s ease; } body.side_menu_slide_with_content .side_menu, body.side_menu_slide_with_content, body.side_menu_slide_with_content header.fixed, body.side_menu_slide_with_content header.fixed_top_header .top_header, body.side_menu_slide_with_content header.fixed_hiding, body.side_menu_slide_with_content footer.uncover{ -webkit-transition: left 0.2s ease, right 0.2s ease; -moz-transition: left 0.2s ease, right 0.2s ease; transition: left 0.2s ease, right 0.2s ease; } body.side_menu_slide_with_content header.sticky{ -webkit-transition: left 0.2s ease, right 0.2s ease, top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -moz-transition: left 0.2s ease, right 0.2s ease, top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); transition: left 0.2s ease, right 0.2s ease, top 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); } body.side_menu_slide_with_content .side_menu{ position: fixed; visibility: visible; -webkit-box-sizing:border-box; box-sizing: border-box; width: 470px; right: -470px; height: 100%; top: 0; z-index: 9999; } body.side_menu_slide_with_content.side_menu_open .side_menu { right: 0; } body.side_menu_slide_with_content.side_menu_open .carousel-inner:not(.relative_position){ left:-470px !important; -webkit-transition: left 0.2s ease; -moz-transition: left 0.2s ease; transition: left 0.2s ease; } body.side_menu_slide_with_content .carousel-inner { left:0 !important; -webkit-transition: left 0.2s ease; -moz-transition: left 0.2s ease; transition: left 0.2s ease; } body.side_menu_slide_with_content.side_menu_open header.fixed, body.side_menu_slide_with_content.side_menu_open header.fixed_top_header .top_header, body.side_menu_slide_with_content.side_menu_open header.fixed_hiding, body.side_menu_slide_with_content.side_menu_open header.sticky{ left: -470px; -webkit-transition: left 0.2s ease; -moz-transition: left 0.2s ease; transition: left 0.2s ease; } /* width 270px start */ body.side_menu_slide_with_content.width_270.side_menu_open .wrapper, body.side_menu_slide_with_content.width_270.side_menu_open footer.uncover{ left: -270px; } body.side_menu_slide_with_content.width_270 .side_menu{ width: 270px; right: -270px; } body.side_menu_slide_with_content.width_270.side_menu_open .side_menu { right: 0; } body.side_menu_slide_with_content.width_270.side_menu_open .carousel-inner:not(.relative_position){ left:-270px !important; } body.side_menu_slide_with_content.width_270.side_menu_open header.fixed, body.side_menu_slide_with_content.width_270.side_menu_open header.fixed_hiding, body.side_menu_slide_with_content.width_270.side_menu_open header.sticky, body.side_menu_slide_with_content.width_270.side_menu_open header.fixed_top_header .top_header{ left: -270px; } /* width 270px end */ /* width 370px start */ body.side_menu_slide_with_content.width_370.side_menu_open .wrapper, body.side_menu_slide_with_content.width_370.side_menu_open footer.uncover{ left: -370px; } body.side_menu_slide_with_content.width_370 .side_menu{ width: 370px; right: -370px; } body.side_menu_slide_with_content.width_370.side_menu_open .side_menu { right: 0; } body.side_menu_slide_with_content.width_370.side_menu_open .carousel-inner:not(.relative_position){ left:-370px !important; } body.side_menu_slide_with_content.width_370.side_menu_open header.fixed, body.side_menu_slide_with_content.width_370.side_menu_open header.fixed_hiding, body.side_menu_slide_with_content.width_370.side_menu_open header.sticky, body.side_menu_slide_with_content.width_370.side_menu_open header.fixed_top_header .top_header{ left: -370px; } /* width 370px end */ /* Side Menu Slides With Content - End */ .side_menu.side_area_alignment_left{ text-align: left; } .side_menu.side_area_alignment_center{ text-align: center; } .side_menu.side_area_alignment_right{ text-align: right; } .side_menu h5, .side_menu h6{ margin: 0 0 12px 0; color: #fff; } .side_menu .widget li { position:relative; } .side_menu .widget ul li.page_item_has_children, .side_menu .widget ul li.menu-item-has-children{ padding-right: 0; border-bottom:none; } .side_menu .widget ul ul{ padding: 6px 0 0 20px; } .side_menu .widget{ margin: 0 0 43px; } .side_menu a, .side_menu li, .side_menu span, .side_menu p, .side_menu .widget.widget_rss li a.rsswidget, .side_menu #wp-calendar caption, .side_menu #wp-calendar th, .side_menu #wp-calendar td{ color: #818181; } .side_menu .side_menu_title{ display: block; margin: 0 0 12px; } .side_menu .widget.widget_nav_menu li:last-child, .side_menu .widget.widget_nav_menu li a{ margin: 0; } .side_menu a.close_side_menu { display: inline-block; position: absolute; top: 29px; right: 25px; width: 13px; height: 13px; line-height: 13px; background-image: url('img/close_side_menu.png'); background-repeat: no-repeat; z-index: 1000; -webkit-transition: all .5s ease; -moz-transition: all .5s ease; -ms-transition: all .5s ease; -o-transition: all .5s ease; transition: all .5s ease; } .side_menu a.close_side_menu:hover{ transform: rotate(180deg); -ms-transform: rotate(180deg); -webkit-transform: rotate(180deg); -o-transform: rotate(180deg); -moz-transform: rotate(180deg); } @media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { .side_menu a.close_side_menu { background-image: url("img/close_side_menu@2x.png"); -o-background-size: 13px 13px; -webkit-background-size: 13px 13px; -moz-background-size: 13px 13px; background-size: 13px 13px; } } @media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { .side_menu a.close_side_menu { background-image: url("img/close_side_menu@2x.png"); -o-background-size: 13px 13px; -webkit-background-size: 13px 13px; -moz-background-size: 13px 13px; background-size: 13px 13px; } } .side_menu.dark a.close_side_menu { background-image: url('img/close_side_menu_dark.png'); } @media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { .side_menu.dark a.close_side_menu { background-image: url("img/close_side_menu_dark@2x.png"); -o-background-size: 13px 13px; -webkit-background-size: 13px 13px; -moz-background-size: 13px 13px; background-size: 13px 13px; } } @media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { .side_menu.dark a.close_side_menu { background-image: url("img/close_side_menu_dark@2x.png"); -o-background-size: 13px 13px; -webkit-background-size: 13px 13px; -moz-background-size: 13px 13px; background-size: 13px 13px; } } /* ========================================================================== End of sidebar and side menu styles ========================================================================== */ .footer_top .widget.widget_nav_menu li{ margin: 0 0 0px; line-height: 22px; } .widget.widget_archive select, .widget.widget_categories select, .widget.widget_text select { width: 100%; overflow: hidden; border: 1px solid transparent; font-size: 13px; background-color: #fff; outline: 0px; color: #818181; font-family: inherit; padding: 2px 4%; height: 37px; } .widget #searchform { display: inline-block; width: 100%; overflow: hidden; background-color: #fff; } .footer_top .widget #searchform{ background-color: transparent; border: 1px solid #6a6a6a; } .header_top #searchform { padding: 0 10px; height: 33px; } .widget.widget_search form.form_focus { border-color: #1abc9c; } .widget.widget_search form input[type="submit"], .header_top #searchform input[type="submit"]{ width: 37px; height: 37px; line-height: 37px; display: inline-block; margin: 0; padding: 0 4%; outline: none; border: none; text-decoration: none; background-color: transparent; color: #b9b9b9; font-family: 'FontAwesome', sans-serif; cursor: pointer; white-space: nowrap; float: right; -webkit-transition: all 0.2s ease-in-out; -moz-transition: all 0.2s ease-in-out; -o-transition: all 0.2s ease-in-out; -ms-transition: all 0.2s ease-in-out; } .footer_top .widget #searchform input[type="submit"]{ color: #6a6a6a; } .header_top #searchform input[type="submit"]{ width: 22px; height: 25px; line-height: 25px; margin: 4px 0 0; background: none; } .widget.widget_search form .screen-reader-text, .header_top #searchform .screen-reader-text{ display: none; } .widget.widget_search form input[type="text"], .header_top #searchform input[type="text"]{ display: inline-block; text-decoration: none; border: 0; outline: 0px; color: #adadad; background-color: transparent; font-family: inherit; margin: 0; padding: 2px 4%; width: 74%; height: 33px; float: left; } .footer_top .widget #searchform input[type="text"]{ color: #6a6a6a; } .header_top #searchform input[type="text"]{ height: 29px; font-size: 12px; } .side_menu .widget #searchform input[type="text"], .footer_top .widget.widget_search form input[type="text"]{ width: 70% !important; } .widget .tagcloud { display:inline-block; width:100%; } .widget .tagcloud a { margin: 0 0px 3px 0; } .side_menu .widget .tagcloud a { color: #fff; } footer{ display: block; width: 100%; margin: 0px auto; z-index: 100; position: relative; } footer.uncover{ position: fixed; bottom: 0px; left: 0px; z-index: 99; -webkit-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -moz-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -o-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -ms-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -webkit-backface-visibility: hidden; } .boxed footer{ width: 100% !important; box-sizing:border-box; -moz-box-sizing:border-box; /* Firefox */ } .right_side_menu_opened footer.uncover{ left: -270px; } footer .container_inner{ position: relative; } .footer_top_holder{ display: block; background-color: #262626; position: relative; } .footer_top{ padding: 72px 0px 52px; } .footer_top_border.in_grid, .footer_bottom_border.in_grid { width: 1100px; margin: 0 auto; } .footer_top.footer_top_full{ padding: 48px 24px; } .footer_top h5{ color: #fff; margin: 0 0 22px; } .footer_top ul{ list-style: none; } .footer_top a, .footer_top p, .footer_top span, .footer_top li, .footer_top .textwidget { color: #818181; word-wrap: break-word; } .footer_top a{ -webkit-transition: color 0.2s ease-in-out; -moz-transition: color 0.2s ease-in-out; -o-transition: color 0.2s ease-in-out; -ms-transition: color 0.2s ease-in-out; } .footer_top a:hover{ color:#fff !important; } .footer_top .four_columns .column2 .column_inner > div, .footer_top .three_columns .column2 .column_inner > div, .footer_top .two_columns_50_50 .column2 .column_inner > div{ margin: 0 0 0 15px; } .footer_top .four_columns .column3 .column_inner > div, .footer_top .three_columns .column3 .column_inner > div{ margin: 0 0 0 10px; } .footer_top .four_columns .column4 .column_inner > div{ margin: 0 0 0 5px; } .footer_top .widget_nav_menu li.menu-item a { margin-bottom: 0; } .footer_top .widget_recent_entries > ul > li, .footer_top .widget_recent_comments > ul > li, .footer_top .widget_meta > ul > li, .footer_top .widget_nav_menu ul li, .footer_top .widget_pages ul li { padding: 0px 0px 17px; position: relative; } .footer_top .widget_nav_menu ul li ul, .footer_top .widget_pages ul li ul{ padding:0 0 0 10px; } .footer_top .widget_recent_entries > ul > li > a, .footer_top .widget_pages > ul > li > a, .footer_top .widget_meta > ul > li > a, .footer_top .widget_nav_menu ul li a, .footer_top .widget_recent_comments > ul > li > a, .footer_top .widget_recent_entries > ul > li > span { display: block; } .footer_top .widget_recent_entries > ul > li > span { color:#9d9d9d; } .footer_bottom_holder { display: block; background-color: #1b1b1b; } .footer_top_holder svg.angled-section polygon{ fill:#1b1b1b; } .footer_bottom { display: table-cell; text-align: center; font-size: 12px; line-height: 22px; height: 53px; width: 1%; vertical-align: middle; } .footer_bottom_columns.three_columns .column1 .footer_bottom, .footer_bottom_columns.two_columns_50_50 .column1 .footer_bottom, .footer_bottom_columns.three_columns .column1 .footer_bottom ul, .footer_bottom_columns.two_columns_50_50 .column1 .footer_bottom ul { text-align: left; } .footer_bottom_columns.three_columns .column3 .footer_bottom, .footer_bottom_columns.two_columns_50_50 .column2 .footer_bottom, .footer_bottom_columns.three_columns .column3 .footer_bottom ul, .footer_bottom_columns.two_columns_50_50 .column2 .footer_bottom ul { text-align: right; } .footer_bottom p, .footer_bottom span { margin: 0px; } .footer_bottom .footer_text_title { display: none; } .footer_bottom ul { list-style: none; text-align: center; } .footer_bottom ul li { display: inline-block; margin-right: 46px; } .footer_bottom ul li:last-child { margin-right: 0; } .footer_bottom ul li a { color: #fff; text-transform: uppercase; font-weight: 500; letter-spacing: 1px; font-size: 13px; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; } .footer_bottom ul li a:hover { color: #818181; } .footer_top .q_social_icon_holder i.simple_social { margin-right:16px; } .footer_top .q_social_icon_holder i.simple_social, .side_menu .q_social_icon_holder i.simple_social{ color: #818181; } .footer_top .q_social_icon_holder:hover i.simple_social, .side_menu .q_social_icon_holder:hover i.simple_social { color: #fff !important; } .footer_top .q_social_icon_holder.normal_social{ margin:0 0 0 0; } .footer_top .q_social_icon_holder:last-child i.simple_social{ margin-right:0; } .footer_top .q_social_icon_holder i.simple_social{ -webkit-transition:all 0.3s ease 0s; -moz-transition:all 0.3s ease 0s; -o-transition:all 0.3s ease 0s; transition:all 0.3s ease 0s; } #back_to_top{ color: #cdcdcd; height: auto; position: fixed; bottom: 65px; margin: 0px; z-index: 10000; -webkit-transition:all 0.3s ease 0s; -moz-transition:all 0.3s ease 0s; -o-transition:all 0.3s ease 0s; transition:all 0.3s ease 0s; right: 25px; opacity: 0; filter: alpha(opacity=0); visibility: hidden; -webkit-backface-visibility: hidden; } #back_to_top.off{ opacity: 0; filter: alpha(opacity=0); right: 25px; } #back_to_top.on{ opacity: 1; filter: alpha(opacity=100); visibility: visible; right: 25px; } #back_to_top .hover{ display: none; } #back_to_top span{ width: 52px; height: 52px; line-height: 52px; text-decoration: none; -o-border-radius: 52px; -moz-border-radius: 52px; -webkit-border-radius: 52px; border-radius: 52px; -webkit-transition:all 0.2s ease 0s; -moz-transition:all 0.2s ease 0s; -o-transition:all 0.2s ease 0s; border:2px solid #e8e8e8; background:transparent; } #back_to_top span i{ font-size: 22px; -webkit-transition: color 0.2s ease 0s; -moz-transition: color 0.2s ease 0s; -o-transition: color 0.2s ease 0s; color:#b0b0b0; line-height: 52px; } #back_to_top:hover span{ background-color:#e8e8e8; } .right_side_menu_opened #back_to_top{ display: none; } /* ========================================================================== Steps shortcode styles ========================================================================== */ .q_steps_holder { width: 100%; text-align: center; } .q_steps_holder_inner { position: relative; display: inline-block; } .q_steps_holder .circle_small, .q_steps_holder .circle_small_inner { width: 192px; height: 192px; } .q_steps_holder .circle_small_wrapper { margin: 0 auto; border-radius: 530px; border: 2px solid transparent; border-top: 2px solid #1abc9c; width: 193px; height: 192px; } .q_steps_holder .circle_small { margin: 0 auto; border: 1px solid #c7c7c7; color: #666666; font-family: inherit; font-size: 26px; border-radius: 500px; text-align: center; } .q_steps_holder .circle_small:hover span, .q_steps_holder .circle_small:hover .step_title { color: #1abc9c !important; } .q_steps_holder .circle_small_inner { display: table-cell; vertical-align: middle; } .q_steps_holder .circle_small_inner span{ font-size: 50px; font-weight:500; line-height:50px; } .q_steps_holder a.circle_small_inner { color: #666666; } .q_steps_holder a.circle_small_inner:hover { color: inherit; } .q_steps_holder .circle_small span { display: block; margin-bottom: 5px; -webkit-transition:color 0.2s ease 0s; -moz-transition:color 0.2s ease 0s; -o-transition:color 0.2s ease 0s; } .q_steps_holder .circle_small .step_title { color: #666666; letter-spacing: 1px; font-size: 16px; -webkit-transition:color 0.2s ease 0s; -moz-transition:color 0.2s ease 0s; -o-transition:color 0.2s ease 0s; } .q_steps_holder .circle_small_holder p { margin-top: 5px; text-align: center; padding: 0 21px; } .q_steps_holder .circle_small_holder { width: 265px; display: inline-block; } .q_steps_holder .circle_small_holder_inner { position: relative; } .q_steps_holder .circle_small_holder:last-child .circle_small_holder_inner .arrow_holder { background: none; } .q_steps_holder.show .circle_small_holder { opacity: 1; -webkit-transform: scale(1); -moz-transform: scale(1); -ms-transform: scale(1); -o-transform: scale(1); transform: scale(1); } .q_steps_holder .circle_small_holder { -webkit-transform: scale(0.7); -moz-transform: scale(0.7); -ms-transform: scale(0.7); -o-transform: scale(0.7); transform: scale(0.7); opacity: 0; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } .q_steps_holder .step1 { left: 40px; top: 85px; -webkit-transition-delay: 0.5s; -moz-transition-delay: 0.5s; -ms-transition-delay: 0.5s; -o-transition-delay: 0.5s; transition-delay: 0.5s; } .q_steps_holder .step1 .circle_small_wrapper { transform:rotate(-25deg); -ms-transform:rotate(-25deg); /* IE 9 */ -webkit-transform:rotate(-25deg); /* Safari and Chrome */ } .q_steps_holder .step1 .circle_small { transform:rotate(25deg); -ms-transform:rotate(25deg); /* IE 9 */ -webkit-transform:rotate(25deg); /* Safari and Chrome */ } .q_steps_holder .step2 { -webkit-transition-delay: 1s; -moz-transition-delay: 1s; -ms-transition-delay: 1s; -o-transition-delay: 1s; transition-delay: 1s; } .q_steps_holder .step2 .circle_small_wrapper { transform:rotate(-175deg); -ms-transform:rotate(-175deg); /* IE 9 */ -webkit-transform:rotate(-175deg); /* Safari and Chrome */ } .q_steps_holder .step2 .circle_small { transform:rotate(175deg); -ms-transform:rotate(175deg); /* IE 9 */ -webkit-transform:rotate(175deg); /* Safari and Chrome */ } .q_steps_holder .step3 { -webkit-transition-delay: 1.5s; -moz-transition-delay: 1.5s; -ms-transition-delay: 1.5s; -o-transition-delay: 1.5s; transition-delay: 1.5s; } .q_steps_holder .step3 .circle_small_wrapper { transform:rotate(25deg); -ms-transform:rotate(25deg); /* IE 9 */ -webkit-transform:rotate(25deg); /* Safari and Chrome */ } .q_steps_holder .step3 .circle_small { transform:rotate(-25deg); -ms-transform:rotate(-25deg); /* IE 9 */ -webkit-transform:rotate(-25deg); /* Safari and Chrome */ } .q_steps_holder .step4 .circle_small_wrapper { transform:rotate(-170deg); -ms-transform:rotate(-170deg); /* IE 9 */ -webkit-transform:rotate(-170deg); /* Safari and Chrome */ } .q_steps_holder .step4 .circle_small { transform:rotate(170deg); -ms-transform:rotate(170deg); /* IE 9 */ -webkit-transform:rotate(170deg); /* Safari and Chrome */ } .q_steps_holder .step4{ -webkit-transition-delay: 2s; -moz-transition-delay: 2s; -ms-transition-delay: 2s; -o-transition-delay: 2s; transition-delay: 2s; } /* ========================================================================== Steps shortcode end styles ========================================================================== */ /* ========================================================================== Separator with text shortcode start styles ========================================================================== */ .vc_text_separator.full{ padding-bottom: 20px; border-top: 1px solid #eaeaea; margin-top: 20px; border-bottom:0; } .vc_text_separator.full.separator_align_center{ text-align: center; } .vc_text_separator.full.separator_align_right{ text-align: right; } .vc_text_separator.full div{ padding: 0px 35px; line-height: 36px; top: -19px; font-size: 12px; color: #fff; font-weight: 700; background-color: #1abc9c; border-radius: 2px; -webkit-border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; border:1px solid transparent; display: inline-block; position: relative; } /* ========================================================================== Separator with text shortcode end styles ========================================================================== */ /* ========================================================================== Separator with icon shortcode start styles ========================================================================== */ .separator_with_icon { color: #818181; display: block; font-size: 18px; line-height: 21px; margin: 0 auto; position: relative; width: 783px; max-width: 100%; text-align: center; } .separator_with_icon:before { border-bottom: 1px solid #818181; border-color: inherit; content: ""; display: inline-block; left: 0; position: absolute; top: 10px; width: 376px; } .separator_with_icon:after { border-bottom: 1px solid #818181; border-color: inherit; content: ""; display: inline-block; position: absolute; right: 0; top: 10px; width: 376px; } @media only screen and (max-width: 1000px){ .separator_with_icon:after, .separator_with_icon:before { max-width: 45%; } } /* ========================================================================== Separator with icon shortcode end styles ========================================================================== */ .page_not_found { text-align:center; margin:0 0 83px; } .page_not_found h2{ margin: 40px 0 20px; font-size:32px; } .page_not_found p{ margin: 15px 0 35px; } .custom_font_holder{ display: block; position: relative; } body div.pp_default .pp_loaderIcon{ background-color: #ffffff; border-radius: 20px; } /* ========================================================================== Pretty Photo style start ========================================================================== */ div.pp_default .pp_top,div.pp_default .pp_top .pp_middle,div.pp_default .pp_top .pp_left,div.pp_default .pp_top .pp_right,div.pp_default .pp_bottom,div.pp_default .pp_bottom .pp_left,div.pp_default .pp_bottom .pp_middle,div.pp_default .pp_bottom .pp_right{height:13px} div.pp_default .pp_top .pp_left{background:url(img/prettyPhoto/sprite.png) -78px -93px no-repeat} div.pp_default .pp_top .pp_middle{background:url(img/prettyPhoto/sprite_x.png) top left repeat-x} div.pp_default .pp_top .pp_right{background:url(img/prettyPhoto/sprite.png) -112px -93px no-repeat} div.pp_default .pp_content .ppt{color:#f8f8f8} div.pp_default .pp_content_container .pp_left{background:url(img/prettyPhoto/sprite_y.png) -7px 0 repeat-y;padding-left:13px} div.pp_default .pp_content_container .pp_right{background:url(img/prettyPhoto/sprite_y.png) top right repeat-y;padding-right:13px} div.pp_default .pp_next:hover{background:url(img/prettyPhoto/sprite_next.png) center right no-repeat;cursor:pointer} div.pp_default .pp_previous:hover{background:url(img/prettyPhoto/sprite_prev.png) center left no-repeat;cursor:pointer} div.pp_default .pp_expand{background:url(img/prettyPhoto/sprite.png) 0 -29px no-repeat;cursor:pointer;width:28px;height:28px} div.pp_default .pp_expand:hover{background:url(img/prettyPhoto/sprite.png) 0 -56px no-repeat;cursor:pointer} div.pp_default .pp_contract{background:url(img/prettyPhoto/sprite.png) 0 -84px no-repeat;cursor:pointer;width:28px;height:28px} div.pp_default .pp_contract:hover{background:url(img/prettyPhoto/sprite.png) 0 -113px no-repeat;cursor:pointer} div.pp_default .pp_close{width:30px;height:30px;background:url(img/prettyPhoto/sprite.png) 2px 1px no-repeat;cursor:pointer} div.pp_default .pp_gallery ul li a{background:url(img/prettyPhoto/default_thumb.png) center center #f8f8f8;border:1px solid #aaa} div.pp_default .pp_social{margin-top:7px} div.pp_default .pp_gallery a.pp_arrow_previous,div.pp_default .pp_gallery a.pp_arrow_next{position:static;left:auto} div.pp_default .pp_nav .pp_play,div.pp_default .pp_nav .pp_pause{background:url(img/prettyPhoto/sprite.png) -51px 1px no-repeat;height:30px;width:30px} div.pp_default .pp_nav .pp_pause{background-position:-51px -29px} div.pp_default a.pp_arrow_previous,div.pp_default a.pp_arrow_next{background:url(img/prettyPhoto/sprite.png) -31px -3px no-repeat;height:20px;width:20px;margin:4px 0 0} div.pp_default a.pp_arrow_next{left:52px;background-position:-82px -3px} div.pp_default .pp_content_container .pp_details{margin-top:5px} div.pp_default .pp_nav{clear:none;height:30px;width:110px;position:relative} div.pp_default .pp_nav .currentTextHolder{font-family:inherit;color:#999;font-size:13px;left:65px;line-height:25px;position:absolute;top:2px;margin:0;padding:0 0 0 10px} div.pp_default .pp_close:hover,div.pp_default .pp_nav .pp_play:hover,div.pp_default .pp_nav .pp_pause:hover,div.pp_default .pp_arrow_next:hover,div.pp_default .pp_arrow_previous:hover{opacity:0.7} div.pp_default .pp_description{font-size:15px;font-weight:300;line-height:14px;margin:10px 50px 10px 0} div.pp_default .pp_bottom .pp_left{background:url(img/prettyPhoto/sprite.png) -78px -127px no-repeat} div.pp_default .pp_bottom .pp_middle{background:url(img/prettyPhoto/sprite_x.png) bottom left repeat-x} div.pp_default .pp_bottom .pp_right{background:url(img/prettyPhoto/sprite.png) -112px -127px no-repeat} div.pp_default .pp_loaderIcon{background:url(img/prettyPhoto/loader.gif) center center no-repeat} div.pp_pic_holder a:focus{outline:none} div.pp_overlay{background-color:#000;display:none;left:0;position:absolute;top:0;width:100%;z-index:9500} div.pp_pic_holder{display:none;position:absolute;width:100px;z-index:10000} .pp_content{height:40px;min-width:40px} * html .pp_content{width:40px} .pp_content_container{position:relative;text-align:left;width:100%} .pp_content_container .pp_left{padding-left:20px} .pp_content_container .pp_right{padding-right:20px} .pp_content_container .pp_details{float:left;margin:10px 0 2px} .pp_description{display:none;margin:0} .pp_social{float:left;margin:0} .pp_social .facebook{float:left;margin-left:5px;width:55px;overflow:hidden} .pp_social .twitter{float:left} .pp_nav{clear:right;float:left;margin:3px 10px 0 0} .pp_nav p{float:left;white-space:nowrap;margin:2px 4px} .pp_nav .pp_play,.pp_nav .pp_pause{float:left;margin-right:4px;text-indent:-10000px} a.pp_arrow_previous,a.pp_arrow_next{display:block;float:left;height:15px;margin-top:3px;overflow:hidden;text-indent:-10000px;width:14px} .pp_hoverContainer{position:absolute;top:0;width:100%;z-index:2000} .pp_gallery{display:none;left:50%;margin-top:-50px;position:absolute;z-index:10000} .pp_gallery div{float:left;overflow:hidden;position:relative} .pp_gallery ul{float:left;height:35px;position:relative;white-space:nowrap;margin:0 0 0 5px;padding:0} .pp_gallery ul a{border:1px rgba(0,0,0,0.5) solid;display:block;float:left;height:33px;overflow:hidden} .pp_gallery ul a img{border:0} .pp_gallery li{display:block;float:left;margin:0 5px 0 0;padding:0} .pp_gallery li.default a{background:url(../images/prettyPhoto/facebook/default_thumbnail.gif) 0 0 no-repeat;display:block;height:33px;width:50px} .pp_gallery .pp_arrow_previous,.pp_gallery .pp_arrow_next{margin-top:7px!important} a.pp_next{display:block;float:right;height:100%;text-indent:-10000px;width:49%} a.pp_previous{display:block;float:left;height:100%;text-indent:-10000px;width:49%} a.pp_expand,a.pp_contract{cursor:pointer;display:none;height:20px;position:absolute;right:30px;text-indent:-10000px;top:10px;width:20px;z-index:20000} a.pp_close{position:absolute;right:0;top:0;display:block;line-height:22px;text-indent:-10000px} .pp_loaderIcon{display:block;height:24px;left:50%;position:absolute;top:50%;width:24px;margin:-12px 0 0 -12px} #pp_full_res{line-height:1!important} #pp_full_res .pp_inline{text-align:left} #pp_full_res .pp_inline p{margin:0 0 15px} div.ppt{color:#fff;display:none;font-size:17px;z-index:9999;margin:0 0 5px 15px} div.pp_default .pp_content{background-color:#fff} div.pp_default #pp_full_res .pp_inline{color:#000} div.pp_default .pp_gallery ul li a:hover,div.pp_default .pp_gallery ul li.selected a,.pp_gallery ul a:hover,.pp_gallery li.selected a{border-color:#fff} div.pp_default .pp_details{position:relative} .pp_top,.pp_bottom{height:20px;position:relative} * html .pp_top,* html .pp_bottom{padding:0 20px} .pp_top .pp_left,.pp_bottom .pp_left{height:20px;left:0;position:absolute;width:20px} .pp_top .pp_middle,.pp_bottom .pp_middle{height:20px;left:20px;position:absolute;right:20px} * html .pp_top .pp_middle,* html .pp_bottom .pp_middle{left:0;position:static} .pp_top .pp_right,.pp_bottom .pp_right{height:20px;left:auto;position:absolute;right:0;top:0;width:20px} .pp_fade,.pp_gallery li.default a img{display:none} body div.pp_overlay{ opacity: 0.7 !important; } body div.pp_default .pp_content_container .pp_left{background: none; padding: 0px;} body div.pp_default .pp_content_container .pp_right{background: none; padding: 0px;} body div.pp_default .pp_top, body div.pp_default .pp_top .pp_middle, body div.pp_default .pp_top .pp_left, body div.pp_default .pp_top .pp_right, body div.pp_default .pp_bottom, body div.pp_default .pp_bottom .pp_left, body div.pp_default .pp_bottom .pp_middle, body div.pp_default .pp_bottom .pp_right{ background: none; display: none; } body div.pp_default .pp_expand{ display: none !important; } body div.pp_default .pp_content{ background: none; } body a.pp_next, body a.pp_previous{ background: none !important; opacity: 0; -webkit-transition: opacity 0.3s ease-in-out; -moz-transition: opacity 0.3s ease-in-out; -ms-transition: opacity 0.3s ease-in-out; -o-transition: opacity 0.3s ease-in-out; transition: opacity 0.3s ease-in-out; } body div.pp_default .pp_content:hover a.pp_next, body div.pp_default .pp_content:hover a.pp_previous{ opacity: 1; } body a.pp_next:after { border: 2px solid #FFFFFF; border-radius: 50px; color: #FFFFFF; content: "\f105"; display: block !important; font-family: 'FontAwesome',serif; font-size: 30px; height: 54px; line-height: 54px; margin: -27px 0 0; position: absolute; right: 25px; text-align: center; top: 50%; width: 54px; text-indent: 0px; } body a.pp_previous:after { border: 2px solid #FFFFFF; border-radius: 50px; color: #FFFFFF; content: "\f104"; display: block !important; font-family: 'FontAwesome',serif; font-size: 30px; height: 54px; line-height: 54px; margin: -27px 0 0; position: absolute; left: 25px; text-align: center; top: 50%; width: 54px; text-indent: 0px; } body div.pp_default .pp_content_container .pp_details{ opacity: 0.7; } body div.pp_default .pp_description{ display: none !important; } body div.pp_default .pp_nav{ float: none; width: auto; margin: 0px; } body div.pp_default .pp_nav .currentTextHolder{ left: auto; position: relative; float: left; padding: 0px 20px; font-family: 'Raleway', sans-serif; font-size: 15px; color: #ffffff; font-weight: 600; } body .pp_gallery{ display: none !important; } body div.pp_default .pp_nav .pp_play, body div.pp_default .pp_nav .pp_pause{ display: none; } body div.pp_default a.pp_arrow_previous, body div.pp_default a.pp_arrow_next{ background: none; position: relative; left: 0px; } body div.pp_default a.pp_arrow_previous:after{ color: #FFFFFF; content: "\f104"; font-family: 'FontAwesome',serif; font-size: 20px; height: 20px; line-height: 20px; text-align: center; width: 20px; text-indent: 0px; position: absolute; top: 0px; left: 0px; } body div.pp_default a.pp_arrow_next:after{ color: #FFFFFF; content: "\f105"; font-family: 'FontAwesome',serif; font-size: 20px; height: 20px; line-height: 20px; text-align: center; width: 20px; text-indent: 0px; position: absolute; top: 0px; right: 0px; } body div.pp_default .pp_close{ background: none; opacity: 1 !important; } body div.pp_default .pp_close:after{ color: #FFFFFF; content: "\f00d"; font-family: 'FontAwesome',serif; font-size: 15px; height: 15px; line-height: 30px; text-align: center; width: 30px; text-indent: 0px; position: absolute; top: 0px; left: 0px; } /* ========================================================================== Pretty Photo style end ========================================================================== */ /**** Audio css ****/ .mejs-container { position: relative; text-align: left; vertical-align: top; text-indent: 0; height: 40px !important; border-radius: 4px; -webkit-border-radius: 4px; -moz-border-radius: 4px; background-color:#fff; } .mejs-container.wp-audio-shortcode { height: 30px !important; border-radius: 0; -webkit-border-radius: 0; -moz-border-radius: 0; } .blog_holder.masonry .mejs-container { border:none; } .blog_holder.small_images article .post_text .post_inner .mejs-container{ margin: 0 0 15px; } .me-plugin { position: absolute; } .mejs-embed, .mejs-embed body { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } .mejs-fullscreen { /* set it to not show scroll bars so 100% will work */ overflow: hidden !important; } .mejs-container-fullscreen { position: fixed; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: 1000; } .mejs-container-fullscreen .mejs-mediaelement, .mejs-container-fullscreen video { width: 100%; height: 100%; } .mejs-clear { clear: both; } /* Start: LAYERS */ .mejs-background { position: absolute; top: 0; left: 0; } .mejs-mediaelement { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-border-radius:4px; -moz-border-radius:4px; border-radius:4px; } .blog_holder.masonry .mejs-mediaelement{ border: none; } .mejs-poster { position: absolute; top: 0; left: 0; background-size: contain; background-position: 50% 50% ; background-repeat: no-repeat ; } :root .mejs-poster img { display: none ; } .mejs-poster img { border: 0; padding: 0; border: 0; } .mejs-overlay { position: absolute; top: 0; left: 0; } .mejs-overlay-play { cursor: pointer; } /* End: LAYERS */ /* Start: CONTROL BAR */ .mejs-container .mejs-controls { position: absolute; list-style-type: none; margin: 0; padding: 0; bottom: 0; left: 0; height: 40px; width: 100%; } .mejs-container .mejs-controls div{ list-style-type: none; background-image: none; display: block; float: left; margin: 0; padding: 0; width: 35px; height: 40px; border: 0; } .mejs-controls .mejs-button button { cursor: pointer; display: block; font-size: 0; line-height: 0; text-decoration: none; margin: 14px 15px 13px 15px; padding: 0; position: absolute; width: 12px; height: 13px; border: 0; background: transparent; } .no-svg .mejs-controls .mejs-button button { background-image: url(img/audio/controls.png); } /* :focus for accessibility */ .mejs-controls .mejs-button button:focus { outline: none; } /* End: CONTROL BAR */ /* Start: Time (Current / Duration) */ .mejs-container .mejs-controls .mejs-time { color: #000; display: block; height: 40px; width: auto; padding: 0; overflow: hidden; text-align: center; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; } .mejs-container .mejs-controls .mejs-time span { color: #000; font-size: 13px; font-weight: 400; line-height: 40px; display: block; float: left; margin: 0; width: auto; } /* End: Time (Current / Duration) */ /* Start: Play/Pause/Stop */ .mejs-controls .mejs-play button { background-image: url(img/audio/play.png); background-repeat: no-repeat; background-position: center; } .mejs-controls .mejs-pause button { background-image: url(img/audio/pause.png); background-repeat: no-repeat; background-position: center; } .mejs-controls .mejs-stop button { background-image: url(img/audio/stop.png); background-repeat: no-repeat; background-position: center; } /* Start: Play/Pause/Stop */ /* Start: Progress Bar */ .mejs-controls div.mejs-time-rail { direction: ltr; width: 200px; } .mejs-controls .mejs-time-rail span { display: block; position: absolute; width: auto; height: 8px; margin: 16px 15px; cursor: pointer; } .mejs-controls .mejs-time-rail .mejs-time-total { background-color: #dddddd; } .mejs-controls .mejs-time-rail .mejs-time-buffering { width: 100%; background-image: -o-linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(224, 222, 222, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(224, 222, 222, 0.15)), color-stop(0.75, rgba(224, 222, 222, 0.15)), color-stop(0.75, transparent), to(transparent)); background-image: -webkit-linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); background-image: -moz-linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); background-image: -ms-linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(-45deg, rgba(224, 222, 222, 0.15) 25%, transparent 25%, transparent 50%, rgba(224, 222, 222, 0.15) 50%, rgba(224, 222, 222, 0.15) 75%, transparent 75%, transparent); -webkit-background-size: 15px 15px; -moz-background-size: 15px 15px; -o-background-size: 15px 15px; background-size: 15px 15px; -webkit-animation: buffering-stripes 2s linear infinite; -moz-animation: buffering-stripes 2s linear infinite; -ms-animation: buffering-stripes 2s linear infinite; -o-animation: buffering-stripes 2s linear infinite; animation: buffering-stripes 2s linear infinite; } @-webkit-keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } @-moz-keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } @-ms-keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } @-o-keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } @keyframes buffering-stripes { from {background-position: 0 0;} to {background-position: 30px 0;} } .mejs-controls .mejs-time-rail .mejs-time-loaded { width: 0; margin: 0px; } .mejs-controls .mejs-time-rail .mejs-time-current { background-color: #1abc9c; margin: 0px; } .mejs-controls .mejs-time-rail .mejs-time-handle { display: none; position: absolute; margin: 0; width: 10px; background-color: #1abc9c; cursor: pointer; top: 0px; text-align: center; } .mejs-controls .mejs-time-rail .mejs-time-float { position: absolute; display: none; width: 36px; height: 15px; top: -35px; margin-left: -18px; text-align: center; color: #000; } .mejs-controls .mejs-time-rail .mejs-time-float-current { margin: 2px; width: 30px; display: block; text-align: center; left: 0; } .mejs-controls .mejs-time-rail .mejs-time-float-corner { display: none; } .mejs-long-video .mejs-controls .mejs-time-rail .mejs-time-float { width: 48px; } .mejs-long-video .mejs-controls .mejs-time-rail .mejs-time-float-current { width: 44px; } .mejs-long-video .mejs-controls .mejs-time-rail .mejs-time-float-corner { left: 18px; } /* End: Progress Bar */ /* Start: Mute/Volume */ .mejs-controls .mejs-volume-button { background-image: url(img/audio/sound.png); background-repeat: no-repeat; background-position: center; } .mejs-controls .mejs-mute button { background-image: url(img/audio/sound.png); background-repeat: no-repeat; background-position: center; } .mejs-controls .mejs-unmute button { background-image: url(img/audio/mute.png); background-repeat: no-repeat; background-position: center; } .mejs-controls .mejs-volume-button { position: relative; } .mejs-controls .mejs-volume-button button{ width: 18px; height: 16px; margin: 12px 6px 12px 11px; } .mejs-controls .mejs-volume-button .mejs-volume-slider { display: none; height: 115px; width: 25px; background-image: url(img/audio/sound.png); background-repeat: no-repeat; background-position: center; top: -115px; left: 0; z-index: 1; position: absolute; margin: 0; } .mejs-controls .mejs-volume-button .mejs-volume-slider .mejs-volume-total { position: absolute; left: 11px; top: 8px; width: 2px; height: 100px; margin: 0; } .mejs-controls .mejs-volume-button .mejs-volume-slider .mejs-volume-current { position: absolute; left: 11px; top: 8px; width: 2px; height: 100px; margin: 0; } .mejs-controls .mejs-volume-button .mejs-volume-slider .mejs-volume-handle { position: absolute; left: 4px; top: -3px; width: 16px; height: 6px; cursor: N-resize; margin: 0; } /* horizontal version */ .mejs-controls div.mejs-horizontal-volume-slider { height: 40px; width: 45px; position: relative; } .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-total { position: absolute; left: 0; top: 16px; width: 35px; height: 8px; margin: 0; padding: 0; font-size: 1px; background-color: #dddddd; } .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current { position: absolute; left: 0; top: 16px; width: 40px; height: 8px; margin: 0; padding: 0; font-size: 1px; background-color: #1abc9c; } .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-handle { display: none; } /* End: Mute/Volume */ /* Start: Error */ .me-cannotplay { } .me-cannotplay a { color: #fff; font-weight: bold; } .me-cannotplay span { padding: 15px; display: block; } /* End: Error */ /* Start: Loop */ .mejs-controls .mejs-loop-off button { background-position: -64px -16px; } .mejs-controls .mejs-loop-on button { background-position: -64px 0; } /* End: Loop */ /* Start: backlight */ .mejs-controls .mejs-backlight-off button { background-position: -80px -16px; } .mejs-controls .mejs-backlight-on button { background-position: -80px 0; } /* End: backlight */ /* ========================================================================== Pie full styles ========================================================================== */ .q_pie_graf_holder, .q_line_graf_holder { display: block; position: relative; overflow: hidden; } .q_pie_graf, .q_line_graf{ margin: 0 22px 0 0; float: left; } .q_pie_graf_legend{ position: relative; float: left; width: 40%; } .q_line_graf_legend{ position: relative; float: left; width: 20%; } .q_pie_graf_legend ul, .q_line_graf_legend ul{ list-style: none; padding:0; } .q_pie_graf_legend ul li, .q_line_graf_legend ul li{ display: block; margin: 0 0 10px 0; } .q_pie_graf_legend ul li .color_holder, .q_line_graf_legend ul li .color_holder{ width: 25px; height: 25px; background-color: #1abc9c; float: left; } .q_pie_graf_legend ul li p, .q_line_graf_legend ul li p{ line-height: 25px; margin: 0; padding: 0 0 0 50px; } /* ========================================================================== WPML styles ========================================================================== */ .header_top .right #lang_sel ul ul img.iclflag, .header_top .right #lang_sel_click ul ul img.iclflag { float: right; top: 11px; margin-right: 0; margin-left: 15px; } .header_top .left #lang_sel ul ul img.iclflag, .header_top .left #lang_sel_click ul ul img.iclflag { float: left; top: 11px; } .header_top .right #lang_sel ul ul, .header_top .right #lang_sel_click ul ul { left: auto; right: 0; } .header_top #lang_sel_click ul ul{ padding: 5px 15px !important; } .header_top .right #lang_sel ul ul li , .header_top .right #lang_sel_click ul ul li { width: 100%; text-align: right; } .header_top .left #lang_sel ul ul li , .header_top .left #lang_sel_click ul ul li { width: 100%; } .header_top #lang_sel ul ul li img.iclflag, .header_top #lang_sel_click ul ul li img.iclflag { position: relative; top: 11px; } .header_top #lang_sel li, .header_top #lang_sel_click li { width: auto; } .header_top #lang_sel, .header_top #lang_sel_click { font-family: inherit; float: left; padding: 0 0 0 0px; z-index: 1000; height: 33px; position: relative; } .header_top #lang_sel ul > li > a, .header_top #lang_sel_click ul > li > a { width: auto; float: none; padding: 0 15px !important; } .header_top #lang_sel > ul > li:hover, .header_top #lang_sel_click > ul > li:hover { border-bottom: none !important; } .header_top #lang_sel > ul > li > a, .header_top #lang_sel_click > ul > li> a { color: #777 !important; line-height: 33px !important; height: 33px; z-index: 2500; font-size:13px; } .header_top #lang_sel > ul > li > a:hover, .header_top #lang_sel_click > ul > li> a:hover{ color: #1abc9c !important; } .header_top .left #lang_sel > ul > li > a, .header_top .left #lang_sel_click > ul > li> a { left: 0; right: auto; } .header_top #lang_sel > ul > li > a:hover, .header_top #lang_sel_click > ul > li> a:hover, .header_top #lang_sel > ul > li:hover > a, .header_top #lang_sel_click > ul > li:hover > a { top: 0px; } .header_top #lang_sel ul > li ul > li, .header_top #lang_sel_click ul > li ul > li{ padding:0px !important; } .header_top #lang_sel ul > li a.lang_sel_sel, .header_top #lang_sel_click ul > li a.lang_sel_sel { background: 0; line-height: 30px; border: 0; padding: 0; } .header_top .right #lang_sel ul > li a.lang_sel_sel, .header_top .right #lang_sel_click ul > li a.lang_sel_sel { text-align: right; } .header_top .right #lang_sel ul > li a.lang_sel_sel { padding-right: 0 !important; } .header_top .left #lang_sel ul > li a.lang_sel_sel { padding-left: 0 !important; } .header_top #lang_sel .lang_sel_sel:after, .header_top #lang_sel_click .lang_sel_sel:after { content: "\f107"; font-family: 'FontAwesome', sans-serif; margin-left: 5px; } .header_top .left #lang_sel ul > li a.lang_sel_sel, .header_top .left #lang_sel_click ul > li a.lang_sel_sel { text-align: left; } .header_bottom .main_menu .submenu-languages { display: none; } .header_top #lang_sel ul ul , .header_top #lang_sel_click ul ul { height: auto; border-top: none; background-color: #262626; z-index:1000; position:absolute; list-style: none; top: 33px; left: -1px; width: 180px; } .header_top #lang_sel ul li ul li a, .header_top #lang_sel ul li ul li a:visited, .header_top #lang_sel_click ul li ul li a, .header_top #lang_sel_click ul li ul li a:visited { background: 0; border: 0; color: #9d9d9d; display: block; height: 38px; white-space: nowrap; font-weight: 600; font-size: 11px; text-transform: uppercase; line-height: 38px; padding: 0 15px !important; border-bottom: 1px solid #303030; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; } .header_top #lang_sel ul li ul li:last-child a, .header_top #lang_sel_click ul li ul li:last-child a{ border-bottom: none; } .header_top #lang_sel ul li ul li a:hover, .header_top #lang_sel_click ul li ul li a:hover{ color: #fff; } .header_top #lang_sel_list { font-family: inherit; height: auto; width: auto; float: left; } .header_top #lang_sel_list ul { border: 0; padding: 0 !important; width: auto; } .header_top #lang_sel_list li { display: inline-block; float: none; width: auto; } .header_top #lang_sel_list ul li a, .header_top #lang_sel_list ul li a:visited { padding: 0 8px 0 8px; border: 0; background: none repeat scroll 0 0 transparent; line-height: 33px; font-size: 13px; color: #818181; margin: 0 !important; -webkit-transition: color 0.3s ease-in-out; -moz-transition: color 0.3s ease-in-out; -ms-transition: color 0.3s ease-in-out; -o-transition: color 0.3s ease-in-out; transition: color 0.3s ease-in-out; } .header_top #lang_sel_list ul li a.lang_sel_sel, .header_top #lang_sel_list ul li a:hover{ color: #1abc9c; } .header_top #lang_sel img.iclflag, .header_top #lang_sel_click img.iclflag, .header_top #lang_sel_list img.iclflag { display: inline; float: none; top: 1px; position: relative; margin-right: 5px; } aside .widget.posts_holder #lang_sel li:after, aside .widget.posts_holder #lang_sel_click li:after{ content:none; } aside .widget #lang_sel_list, section.side_menu #lang_sel_list, footer #lang_sel_list { height: auto; font-family: inherit; width:100%; } aside .widget #lang_sel_list li, section.side_menu #lang_sel_list li, footer #lang_sel_list li{ float: none; margin-bottom: 0px !important; padding: 9px 10px 9px 0px !important; width:auto; } footer #lang_sel_list li{ padding: 5px 5px 5px 0px !important; } aside .widget #lang_sel_list li a, aside .widget #lang_sel li a, aside .widget #lang_sel_click li a, section.side_menu #lang_sel_list li a, section.side_menu #lang_sel li a, section.side_menu #lang_sel_click li a, footer #lang_sel_list li a, footer #lang_sel li a, footer #lang_sel_click li a { font-family: inherit; font-size: 13px; font-weight: 400; border: 0; color: #777; } aside .widget #lang_sel_list li a, section.side_menu #lang_sel_list li a, aside .widget #lang_sel_list li a, footer #lang_sel_list li a { display: inline; } aside .widget #lang_sel li, aside .widget #lang_sel_click li, section.side_menu #lang_sel li, section.side_menu #lang_sel_click li, footer #lang_sel li, footer #lang_sel_click li { margin-bottom: 0; } aside .widget #lang_sel, aside .widget #lang_sel_click, section.side_menu #lang_sel, section.side_menu #lang_sel_click, footer #lang_sel, footer #lang_sel_click { width: 100%; } aside .widget #lang_sel > ul > li > a, aside .widget #lang_sel_click > ul > li > a, section.side_menu #lang_sel > ul > li > a, section.side_menu #lang_sel_click > ul > li > a, footer #lang_sel > ul > li > a, footer #lang_sel_click > ul > li > a { height: 35px; line-height: 35px !important; font-family: inherit; font-weight: 300; padding-left: 13px; font-weight: 300; background-image: url(img/wc_select_arrow.png) !important; background-repeat: no-repeat; background-position: right; } footer #lang_sel > ul > li > a, footer #lang_sel_click > ul > li > a, section.side_menu #lang_sel > ul > li > a, section.side_menu #lang_sel_click > ul > li > a { background-image: url(img/wc_select_arrow_footer.png) !important; background-repeat: no-repeat; background-position: right; } aside .widget #lang_sel > ul > li a, aside .widget #lang_sel_click > ul > li a{ background-color: #fff; } footer #lang_sel > ul > li a, footer #lang_sel_click > ul > li a, section.side_menu #lang_sel > ul > li a, section.side_menu #lang_sel_click > ul > li a{ background-color: #262626 !important; } footer #lang_sel ul li a, footer #lang_sel ul ul a, footer #lang_sel_click ul li a, footer #lang_sel_click ul ul a, footer #lang_sel_click ul ul a span, section.side_menu #lang_sel ul li a, section.side_menu #lang_sel ul ul a, section.side_menu #lang_sel ul ul a:visited, section.side_menu #lang_sel_click > ul > li > a, section.side_menu #lang_sel_click ul ul a, section.side_menu #lang_sel_click ul ul a:visited{ color: #777 !important; } aside .widget #lang_sel > ul li a, aside .widget #lang_sel ul ul a, aside .widget #lang_sel_click > ul li a, aside .widget #lang_sel_click ul ul a, aside .widget #lang_sel_list li a{ color: #adadad; font-family: 'Raleway', sans-serif; background-color: #fff; } aside .widget #lang_sel a.lang_sel_sel:hover, aside .widget #lang_sel_click a.lang_sel_sel:hover, aside .widget #lang_sel ul ul a:hover, aside .widget #lang_sel_click ul ul a:hover, aside .widget #lang_sel_list li a.lang_sel_sel, aside .widget #lang_sel_list li a:hover{ color: #1abc9c; } footer #lang_sel_list li a:hover, footer #lang_sel a.lang_sel_sel, footer #lang_sel a.lang_sel_sel:hover, footer #lang_sel ul ul a:hover, footer #lang_sel_click a.lang_sel_sel, footer #lang_sel_click ul ul a:hover, footer #lang_sel_click ul ul a:hover span, footer #lang_sel_list a.lang_sel_sel, footer #lang_sel_list ul ul a:hover, footer #lang_sel_list ul ul a:hover span, section.side_menu a.lang_sel_sel, section.side_menu #lang_sel ul li a.lang_sel_sel, section.side_menu #lang_sel_click ul li a.lang_sel_sel, section.side_menu #lang_sel_list li a:hover, section.side_menu #lang_sel ul ul a:hover, section.side_menu #lang_sel_click ul ul a:hover, section.side_menu #lang_sel_click ul ul a:hover span{ color: #fff !important; } aside .widget #lang_sel li, aside .widget #lang_sel_click li, section.side_menu #lang_sel li, section.side_menu #lang_sel_click li, footer #lang_sel li, footer #lang_sel_click li { width: 100%; padding:0; border:none; } aside .widget #lang_sel ul ul, aside .widget #lang_sel_click ul ul{ width: 100%; top:32px; height: auto; border: 0; z-index: 1000; padding:3px 0 0 0; overflow:hidden; } footer #lang_sel ul ul, footer #lang_sel_click ul ul , section.side_menu #lang_sel ul ul, section.side_menu #lang_sel_click ul ul{ width: 100%; top:32px; border: 0; } section.side_menu #lang_sel li a:after, section.side_menu #lang_sel li:before{ display:none; } section.side_menu #lang_sel ul ul a, #lang_sel ul ul a:visited{ padding: 8px 10px; } footer #lang_sel ul ul, footer #lang_sel_click ul ul, section.side_menu #lang_selul ul, section.side_menu #lang_sel_click ul ul { left: 0 !important; } aside .widget #lang_sel ul ul a, aside .widget #lang_sel_click ul ul a, aside .widget #lang_sel ul ul a:visited, aside .widget #lang_sel_click ul ul a:visited{ padding: 10px 13px; } footer #lang_sel ul ul a, footer #lang_sel_click ul ul a, footer #lang_sel ul ul a:visited, footer #lang_sel_click ul ul a:visited{ padding: 10px 13px; } aside .widget #lang_sel_list.lang_sel_list_vertical ul, section.side_menu #lang_sel_list.lang_sel_list_vertical ul, footer #lang_sel_list.lang_sel_list_vertical ul { height: auto; border-top: none; } aside .widget #lang_sel_list.lang_sel_list_vertical a, aside .widget #lang_sel_list.lang_sel_list_vertical a:visited, section.side_menu #lang_sel_list.lang_sel_list_vertical a, section.side_menu #lang_sel_list.lang_sel_list_vertical a:visited, footer #lang_sel_list.lang_sel_list_vertical a, footer #lang_sel_list.lang_sel_list_vertical a:visited { border: none; padding: 0; } section.side_menu #lang_sel_list.lang_sel_list_vertical a, section.side_menu #lang_sel_list.lang_sel_list_vertical a:visited, section.side_menu #lang_sel_list.lang_sel_list_horizontal a, section.side_menu #lang_sel_list.lang_sel_list_horizontal a:visited, footer #lang_sel_list.lang_sel_list_vertical a, footer #lang_sel_list.lang_sel_list_vertical a:visited, footer #lang_sel_list.lang_sel_list_horizontal a, footer #lang_sel_list.lang_sel_list_horizontal a:visited { background: transparent; } aside #lang_sel img.iclflag, aside #lang_sel_click img.iclflag, section.side_menu #lang_sel img.iclflag, section.side_menu #lang_sel_click img.iclflag, footer #lang_sel img.iclflag, footer #lang_sel_click img.iclflag, footer #lang_sel_list.lang_sel_list_horizontal a img, footer #lang_sel_list.lang_sel_list_vertical a img { margin-right: 5px; } footer #lang_sel_list.lang_sel_list_horizontal a:hover, footer #lang_sel_list.lang_sel_list_vertical a:hover, .side_menu #lang_sel_list.lang_sel_list_horizontal a:hover, .side_menu #lang_sel_list.lang_sel_list_vertical a:hover { color: #fff; } footer #lang_sel_list.lang_sel_list_horizontal a, footer #lang_sel_list.lang_sel_list_vertical a, .side_menu #lang_sel_list.lang_sel_list_horizontal a, .side_menu #lang_sel_list.lang_sel_list_vertical a { color: #777; } #lang_sel_footer { background-color: #111111; border: none; z-index: 1500; position: relative; font-family: 'Roboto', sans-serif; } #lang_sel_footer a { font-size: 13px; color: #777; -webkit-transition: color 0.3s ease 0s !important; -moz-transition: color 0.3s ease 0s !important; -o-transition: color 0.3s ease 0s !important; -ms-transition: color 0.3s ease 0s !important; transition: color 0.3s ease 0s !important; } #lang_sel_footer a:hover { color: #fff; -webkit-transition: color 0.3s ease 0s !important; -moz-transition: color 0.3s ease 0s !important; -o-transition: color 0.3s ease 0s !important; -ms-transition: color 0.3s ease 0s !important; transition: color 0.3s ease 0s !important; } #lang_sel_footer a img { margin-right: 15px; } /* ========================================================================== End of WPML styles ========================================================================== */ .ls-nav-prev, .ls-nav-next { position: absolute; display: block !important; line-height: 40px; margin: -20px 0 0; top: 60%; z-index: 90; cursor: pointer; opacity: 0.6 !important; filter: alpha(opacity=60) !important; } .ls-nav-prev{ background-image:none !important; background-color: transparent !important; height: 54px; width: 54px; border: 2px solid #fff !important; line-height: 54px; font-size: 14px; position: absolute; top: 50%; margin-top: -27px; text-align: center; z-index: 10; -webkit-transition: opacity .3s ease 0s !important; -moz-transition: opacity .3s ease 0s !important; -o-transition: opacity .3s ease 0s !important; transition: opacity .3s ease-in-out !important; opacity: 0.7; -webkit-border-radius: 56px; -moz-border-radius: 56px; -ms-border-radius: 56px; -o-border-radius: 56px; border-radius: 56px; position: absolute; left: 23px; } .ls-nav-prev:after { position: absolute; left: 0 !important; color: #fff; width: 100%; height: 100%; content: "\f104"; font-family: 'FontAwesome', serif; line-height: 54px; text-align:center; display: block !important; font-size:30px; } .ls-nav-next{ background-image:none !important; background-color: transparent !important; height: 54px; width: 54px; border: 2px solid #fff !important; line-height: 54px; font-size: 14px; position: absolute; top: 50%; margin-top: -27px; text-align: center; z-index: 10; -webkit-transition: opacity .3s ease 0s; -moz-transition: opacity .3s ease 0s; -o-transition: opacity .3s ease 0s; transition: opacity .3s ease-in-out; opacity: 0; -webkit-border-radius: 56px; -moz-border-radius: 56px; -ms-border-radius: 56px; -o-border-radius: 56px; border-radius: 56px; right: 23px; } .ls-nav-next:after { position: absolute; left: 0 !important; color: #fff; width: 100%; height: 100%; content: "\f105"; font-family: 'FontAwesome', serif; line-height: 54px; text-align:center; display: block !important; font-size:30px; } .ls-nav-prev:hover, .ls-nav-next:hover{ opacity: 1 !important; filter: alpha(opacity=100) !important; } .element_from_left, .element_from_right, .element_from_top, .element_from_bottom, .element_from_fade{ display: inline-block; width: 100%; } .touch .no_animation_on_touch .element_from_left>div, .touch .no_animation_on_touch .element_from_right>div, .touch .no_animation_on_touch .element_from_top>div, .touch .no_animation_on_touch .element_from_bottom>div, .touch .no_animation_on_touch .element_from_fade>div, .touch .no_animation_on_touch .element_transform>div{ opacity: 1; filter: alpha(opacity = 100); -webkit-transform: scale(1); -moz-transform: scale(1); -o-transform: scale(1); transform: scale(1); -webkit-animation: none; -moz-animation: none; -o-animation: none; animation: none; } .element_from_left > div, .element_from_right > div, .element_from_top > div, .element_from_bottom > div, .element_from_fade > div { opacity: 0; display: inline-block; width: 100%; filter: alpha(opacity = 0); } .element_transform > div{ opacity: .2; -webkit-transform: scale(0.5); -moz-transform: scale(0.5); -o-transform: scale(0.5); transform: scale(0.5); } .element_from_fade.element_from_fade_on > div { opacity: 1; filter: alpha(opacity = 100); -webkit-transition: opacity .8s ease 0s; -moz-transition: opacity .8s ease 0s; -o-transition: opacity .8s ease 0s; -webkit-backface-visibility: hidden; } .element_from_left.element_from_left_on > div { -webkit-animation: element-from-left 0.7s 1 ease-in-out; -moz-animation: element-from-left 0.7s 1 ease-in-out; -o-animation: element-from-left 0.7s 1 ease-in-out; animation: element-from-left 0.7s 1 ease-in-out; opacity: 1; filter: alpha(opacity = 100); -webkit-backface-visibility: hidden; } .element_from_right.element_from_right_on>div { -webkit-animation: element-from-right 0.7s 1 ease-in-out; -moz-animation: element-from-right 0.7s 1 ease-in-out; -o-animation: element-from-right 0.7s 1 ease-in-out; animation: element-from-right 0.7s 1 ease-in-out; opacity: 1; filter: alpha(opacity = 100); -webkit-backface-visibility: hidden; } .element_from_top.element_from_top_on>div { -webkit-animation: element-from-top 0.7s 1 ease-in-out; -moz-animation: element-from-top 0.7s 1 ease-in-out; -o-animation: element-from-top 0.7s 1 ease-in-out; animation: element-from-top 0.7s 1 ease-in-out; opacity: 1; filter: alpha(opacity = 100); -webkit-backface-visibility: hidden; } .element_from_bottom.element_from_bottom_on>div { -webkit-animation: element-from-bottom 0.7s 1 ease-in-out; -moz-animation: element-from-bottom 0.7s 1 ease-in-out; -o-animation: element-from-bottom 0.7s 1 ease-in-out; animation: element-from-bottom 0.7s 1 ease-in-out; opacity: 1; filter: alpha(opacity = 100); -webkit-backface-visibility: hidden; } .element_transform.element_transform_on>div { -webkit-animation: element-transform .4s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275); -moz-animation: element-transform .4s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275); -o-animation: element-transform .4s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275); animation: element-transform .4s 1 cubic-bezier(0.175, 0.885, 0.320, 1.275); opacity: 1; -webkit-transform: scale(1); -moz-transform: scale(1); -o-transform: scale(1); transform: scale(1); } @-webkit-keyframes element-from-left { 0% { -webkit-transform: translate(-20%, 0); opacity: 0; } 100% { -webkit-transform: translate(0, 0); opacity: 1; } } @-moz-keyframes element-from-left { 0% { -moz-transform: translate(-20%, 0); opacity: 0; } 100% { -moz-transform: translate(0, 0); opacity: 1; } } @-o-keyframes element-from-left { 0% { -o-transform: translate(-20%, 0); opacity: 0; } 100% { -o-transform: translate(0, 0); opacity: 1; } } @keyframes element-from-left { 0% { transform: translate(-20%, 0); opacity: 0; } 100% { transform: translate(0, 0); opacity: 1; } } @-webkit-keyframes element-from-right { 0% { -webkit-transform: translate(20%, 0); opacity: 0; } 100% { -webkit-transform: translate(0, 0); opacity: 1; } } @-moz-keyframes element-from-right { 0% { -moz-transform: translate(20%, 0); opacity: 0; } 100% { -moz-transform: translate(0, 0); opacity: 1; } } @-o-keyframes element-from-right { 0% { -o-transform: translate(20%, 0); opacity: 0; } 100% { -o-transform: translate(0, 0); opacity: 1; } } @keyframes element-from-right { 0% { transform: translate(20%, 0); opacity: 0; } 100% { transform: translate(0, 0); opacity: 1; } } @-webkit-keyframes element-from-bottom { 0% { -webkit-transform: translate(0, 30%); opacity: 0; } 100% { -webkit-transform: translate(0, 0); opacity: 1; } } @-moz-keyframes element-from-bottom { 0% { -moz-transform: translate(0, 30%); opacity: 0; } 100% { -moz-transform: translate(0, 0); opacity: 1; } } @-o-keyframes element-from-bottom { 0% { -o-transform: translate(0, 30%); opacity: 0; } 100% { -o-transform: translate(0, 0); opacity: 1; } } @keyframes element-from-bottom { 0% { transform: translate(0, 30%); opacity: 0; } 100% { transform: translate(0, 0); opacity: 1; } } @-webkit-keyframes element-from-top { 0% { -webkit-transform: translate(0, -30%); opacity: 0; } 100% { -webkit-transform: translate(0, 0); opacity: 1; } } @-moz-keyframes element-from-top { 0% { -moz-transform: translate(0, -30%); opacity: 0; } 100% { -moz-transform: translate(0, 0); opacity: 1; } } @-o-keyframes element-from-top { 0% { -o-transform: translate(0, -30%); opacity: 0; } 100% { -o-transform: translate(0, 0); opacity: 1; } } @keyframes element-from-top { 0% { transform: translate(0, -30%); opacity: 0; } 100% { transform: translate(0, 0); opacity: 1; } } @-webkit-keyframes element-transform { 0% { -webkit-transform: scale(0.3); opacity: .1; } 100% { -webkit-transform: scale(1); opacity: 1; } } @-moz-keyframes element-transform { 0% { -moz-transform: scale(0.3); opacity: .1; } 100% { -moz-transform: scale(1); opacity: 1; } } @-o-keyframes element-transform { 0% { -o-transform: scale(0.3); opacity: .1; } 100% { -o-transform: scale(1); opacity: 1; } } @keyframes element-transform { 0% { transform: scale(0.3); opacity: .1; } 100% { transform: scale(1); opacity: 1; } } /* ========================================================================== Image With Text Over start styles ========================================================================== */ .q_image_with_text_over{ display: inline-block; position: relative; margin: 0px; width: 100%; } .q_image_with_text_over.one_half{ width: 50%; } .q_image_with_text_over.one_third{ width: 33.33%; } .q_image_with_text_over.one_fourth{ width: 25%; } .q_image_with_text_over img{ display: block; position: relative; width: 100%; z-index: 10; } .q_image_with_text_over .shader{ position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; z-index: 20; background-color: rgba(0,0,0,0.5); } .q_image_with_text_over .text{ position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; z-index: 30; text-align: center; } .q_image_with_text_over table{ position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; width: 100%; height: 100%; } .q_image_with_text_over table td{ padding: 0px; vertical-align: middle; background: none !important; } .q_image_with_text_over .caption, .q_image_with_text_over .icon_holder{ opacity: 1; filter: alpha(opacity = 100); -webkit-transition: opacity 0.4s ease-in-out; -moz-transition: opacity 0.4s ease-in-out; -o-transition: opacity 0.4s ease-in-out; -ms-transition: opacity 0.4s ease-in-out; -webkit-transform: translateZ(0px); } .q_image_with_text_over .caption{ line-height: 1em; } .q_image_with_text_over .text p, .q_image_with_text_over .caption, .q_image_with_text_over .icon_holder{ color: #fff; } .q_image_with_text_over .icon_holder{ display: inline-block; } .q_image_with_text_over .icon_holder.fa-2x{ padding: 0.67em 0.7em; } .q_image_with_text_over .icon_holder.fa-3x{ padding: 0.6em 0.62em; } .q_image_with_text_over .caption{ margin: 2% 0 0; } .q_image_with_text_over .caption.no_icon{ margin: 0; } .q_image_with_text_over .desc{ margin: 0px 30px; opacity: 0; filter: alpha(opacity = 0); -webkit-transition: opacity 0.4s ease-in-out; -moz-transition: opacity 0.4s ease-in-out; -o-transition: opacity 0.4s ease-in-out; -ms-transition: opacity 0.4s ease-in-out; -webkit-backface-visibility:hidden; -webkit-transform: translateZ(0px); color:#fff; } .q_image_with_text_over .text:hover .caption, .q_image_with_text_over .text:hover .icon_holder{ opacity: 0; filter: alpha(opacity = 0); } .q_image_with_text_over .text:hover .desc{ opacity: 1; filter: alpha(opacity = 100); } /* ========================================================================== Image With Text Over end styles ========================================================================== */ /* ========================================================================== Team start styles ========================================================================== */ .q_team{ background-color:#fff; overflow:hidden; } .q_team_inner{ overflow:hidden; width: 100%; } .q_team .q_team_image{ position:relative; } .q_team .q_team_image img{ width:100%; vertical-align: middle; } .q_team .q_team_description_wrapper { position: absolute; top: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.95); opacity: 0; -webkit-transition: opacity 0.3s ease-in-out; -moz-transition: opacity 0.3s ease-in-out; -ms-transition: opacity 0.3s ease-in-out; -o-transition: opacity 0.3s ease-in-out; transition: opacity 0.3s ease-in-out; cursor: default; } .q_team .q_team_image:hover .q_team_description_wrapper { opacity: 1; } .q_team .q_team_description { display: table; width: 100%; height: 100%; } .q_team .q_team_description_inner { display: table-cell; vertical-align: middle; text-align: center; padding: 0 50px; } .q_team .q_team_description_inner p { color: #303030; } .q_team .q_team_text{ padding:23px 16px 23px; border-style: none; border-width: 1px; border-color: #f6f6f6; border-top:none !important; } .q_team .q_team_title_holder{ margin: 0 0 9px; text-align: center; } .q_team .q_team_title_holder .q_team_name{ margin-bottom: 7px; } .q_team .q_team_text_inner .separator{ background-color: #1abc9c; margin-bottom: 16px !important; } .q_team .q_team_social_holder{ position: relative; text-align: center; } .q_team .q_team_social_holder .q_social_icon_holder i.simple_social{ font-size: 19px; color: #bcbcbc; } .q_team .q_team_social_holder .q_social_icon_holder:hover i.simple_social { color: #1abc9c; } /*Info on hover style*/ .q_team.info_on_hover .q_team_description_wrapper{ position: relative; opacity: 1; background-color: transparent; box-sizing: border-box; } .q_team.info_on_hover .q_team_text{ position: absolute; top: 0; width: 100%; height: 100%; background-color: rgba(21, 21, 21, 0.78); padding: 0; opacity: 0; -webkit-transition: opacity 0.3s ease-in-out; -moz-transition: opacity 0.3s ease-in-out; -ms-transition: opacity 0.3s ease-in-out; -o-transition: opacity 0.3s ease-in-out; transition: opacity 0.3s ease-in-out; } .q_team.info_on_hover .q_team_text_holder{ display: table; width: 100%; height: 100%; } .q_team.info_on_hover .q_team_text_holder_inner{ display: table-cell; vertical-align: middle; } .q_team.info_on_hover .q_team_image:hover .q_team_text{ opacity: 1; } .q_team.info_on_hover .q_team_title_holder .q_team_name, .q_team.info_on_hover .q_team_title_holder span, .q_team.info_on_hover .q_team_social_holder i.simple_social{ color: #fff; } /* ========================================================================== Team end styles ========================================================================== */ /* ========================================================================== Service shortcode styles ========================================================================== */ .circle_item .circle { font-size: 15px; line-height: 13px; width: 155px; height: 155px; display: inline-block; text-align: center; color: #000; background-color: #fbfbfb; -o-border-radius: 182px; -moz-border-radius: 182px; -webkit-border-radius: 182px; border-radius: 182px; -webkit-transition: all .5s ease 0s; -moz-transition: all .5s ease 0s; -o-transition: all .5s ease 0s; -webkit-transform: translateZ(0px); -moz-transform: translateZ(0px); } .circle_item .circle div { padding: 69.5px 0; } .circle_left { width: 100%; display: inline-block; margin: 0 0 25px 0; } .circle_left .circle { float: left; } .circle_left .text { padding: 0 10px 0 170px; } .circle_top { width: 100%; display: inline-block; text-align: center; margin: 0 0 25px 0; } .circle_top .circle { margin: 0 auto; } .circle_top .text { margin: 25px 0 0; } .circle_top .text p { margin: 0; } .circle_item .circle a { text-decoration: none; } .circle_item .circle:hover { background-color: #1abc9c; color: #fff; } .circle_item .circle.hover { cursor: pointer; } .circle_item .circle:hover a { color: #fff; } .fade_in_circle_holder { display: block; cursor: pointer; overflow: hidden; } .fade_in_circle_holder.animate_circle { opacity: 1; filter: alpha(opacity=100); -webkit-transform: scale(1); -moz-transform: scale(1); -o-transform: scale(1); -ms-transform: scale(1); transform: scale(1); } .fade_in_circle_holder { display: table; position: relative; overflow: hidden; opacity: 0; filter: alpha(opacity=0); -webkit-transform: scale(0.1); -moz-transform: scale(0.1); -o-transform: scale(0.1); -ms-transform: scale(0.1); -webkit-transition: all .4s ease-in-out; -moz-transition: all .4s ease-in-out; -o-transition: all .4s ease-in-out; -ms-transition: all .4s ease-in-out; transition: all .4s ease-in-out; -webkit-backface-visibility: hidden; z-index: 2000; } .touch .no_animation_on_touch .fade_in_circle_holder{ opacity: 1; filter: alpha(opacity=100); -webkit-transform: scale(1); -moz-transform: scale(1); -o-transform: scale(1); -ms-transform: scale(1); transform: scale(1); } /* ========================================================================== Image hover styles ========================================================================== */ .image_hover { position: relative; display: inline-block; width: 100%; } .image_hover .images_holder { position: relative; display: inline-block; } .image_hover .images_holder img.hover_image { position: absolute; top: 0; left: 0; } .image_hover .images_holder img.active_image { opacity: 1; filter: alpha(opacity = 100); position: relative; display: block; } .image_hover .images_holder img.active_image, .image_hover .images_holder img.hover_image, .image_hover.hovered.show .images_holder img.active_image, .image_hover.hovered.show .images_holder img.hover_image { -webkit-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; -webkit-backface-visibility:hidden; -webkit-transform: translateZ(0px); } .image_hover .images_holder img.hover_image { opacity: 0; filter: alpha(opacity = 0); } .image_hover .images_holder:hover img.active_image, .image_hover.hovered.show .images_holder img.active_image { opacity: 0; filter: alpha(opacity = 0); } .image_hover .images_holder:hover img.hover_image, .image_hover.hovered.show .images_holder img.hover_image { opacity: 1; filter: alpha(opacity = 100); } /* ========================================================================== Call to action widget styles ========================================================================== */ /*.content_bottom{ position: relative; z-index: 100; }*/ .qode_call_to_action.container { background-color: #1abc9c; } .qode_call_to_action.in_grid { -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; } .qode_call_to_action.container .container_inner { padding: 40px 0; } .call_to_action_text_wrapper p { font-size: 19px; font-weight: 300; line-height: 1.692307692307692em; color: #fff; text-align: center; } .qode_call_to_action .call_to_action_text_wrapper { line-height: 40px; } .qode_call_to_action .qbutton{ position: static; } .call_to_action_button_wrapper { text-align: left; } .call_to_action_button_wrapper.left { text-align: left; } .qode_call_to_action .two_columns_75_25>.column2.left>.column_inner { padding: 0 20px 0 0; } .qode_call_to_action.in_grid .two_columns_75_25>.column2.left>.column_inner { padding-left: 28px; } .qode_call_to_action.in_grid .two_columns_75_25>.column2>.column_inner { padding-right: 28px; } .qode_call_to_action.in_grid .two_columns_75_25>.column1.left>.column_inner { padding-right: 28px; } .qode_call_to_action.in_grid .two_columns_75_25>.column1>.column_inner { padding-left: 28px; } .qode_call_to_action .two_columns_75_25>.column1.left>.column_inner { padding: 0; } .qode_call_to_action .two_columns_75_25>.column1.left { text-align: right; } /* ========================================================================== * Bootstrap v3.0.0 * * Copyright 2013 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world by @mdo and @fat. * normalize.css v2.1.0 | MIT License | git.io/normalize ========================================================================== */ .carousel { position: relative; } .carousel-inner { position: relative; width: 100%; overflow: hidden; } .boxed .carousel-inner{ width: 1150px; left: auto !important; } .carousel-inner .video{ position: static; left: 0; direction: ltr; } .carousel-inner > .item { position: relative; display: none; -webkit-transition: 0.6s ease-in-out left; transition: 0.6s ease-in-out left; } .carousel-inner > .item > img, .carousel-inner > .item > a > img { display: block; height: auto; max-width: 100%; line-height: 1; } .carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev { display: block; } .carousel-inner > .active { left: 0; } .carousel-inner > .next, .carousel-inner > .prev { position: absolute; top: 0; width: 100%; } .carousel-inner > .next { left: 100%; } .carousel-inner > .prev { left: -100%; } .carousel-inner > .next.left, .carousel-inner > .prev.right { left: 0; } .carousel-inner > .active.left { left: -100%; } .carousel-inner > .active.right { left: 100%; } /* part for fading adnimation - start */ .carousel.fade .item { -webkit-transition: opacity 0.5s ease-in-out; -moz-transition: opacity 0.5s ease-in-out; -ms-transition: opacity 0.5s ease-in-out; -o-transition: opacity 0.5s ease-in-out; transition: opacity 0.5s ease-in-out; opacity: 1; filter: alpha(opacity=100); } .carousel.fade .active.left, .carousel.fade .active.right { opacity: 0; filter: alpha(opacity=0); } .carousel.fade .active.item { opacity: 1; filter: alpha(opacity=100); } .carousel.fade .active.left, .carousel.fade .active.right { left: 0; z-index: 2; opacity: 0; filter: alpha(opacity=0); } .carousel.fade .next, .carousel.fade .prev { left: 0; z-index: 1; } /* part for fading adnimation - end */ .carousel-indicators { position: absolute; bottom: 20px; left: 50%; z-index: 15; width: 60%; padding-left: 0; margin-left: -30%; text-align: center; list-style: none; } .carousel-indicators li { display: inline-block; width: 8px; height: 8px; margin: 1px; text-indent: -999px; cursor: pointer; border-radius: 10px; } .carousel-caption { position: absolute; right: 15%; bottom: 40px; left: 15%; z-index: 10; padding-top: 20px; padding-bottom: 20px; color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); } .carousel-caption .btn { text-shadow: none; } @media screen and (min-width: 768px) { .carousel-control .icon-prev, .carousel-control .icon-next { width: 30px; height: 30px; margin-top: -15px; margin-left: -15px; font-size: 30px; } .carousel-caption { right: 20%; left: 20%; padding-bottom: 30px; } } /* ==== Carousel Custom - Start ==== */ .carousel { margin-bottom: 0; } .carousel.full_screen { height: 1500px; } .qode_slider_preloader{ width: 100%; background-color: #1c1c1c; position: absolute; z-index: 20; } .qode_slider_preloader{ height: 1500px; } .qode_slider_preloader .ajax_loader{ position: absolute; } .carousel-inner .slider_content_outer{ position: relative; height: 100%; width: 1100px; margin: 0px auto; z-index: 12; } .carousel-inner .slider_content { position: absolute; width: 100%; } .carousel-inner .slider_content .slide_anchor_holder { margin-top: 8%; } .carousel-inner .item.dark .slider_content .text .slide_anchor_holder .slide_anchor_button { color: #000; } .carousel-inner .slider_content .slide_anchor_holder .slide_anchor_button { font-size: 51px; color: #fff; } .carousel-inner .slider_content .thumb{ opacity: 0; filter: alpha(opacity = 0); height: 100%; display: inline-block; vertical-align: middle; } .carousel-inner .slider_content.left{ text-align: left; } .carousel-inner .slider_content.right{ text-align: right; } .carousel-inner .slider_content.left .thumb, .carousel-inner .slider_content.right .thumb{ display: inline-block; } .carousel-inner .slider_content.center .thumb{ text-align: center; } .carousel-inner .slider_content.center { text-align: center; } /*----- SVG ----- */ .qode_slide-svg-holder svg{ opacity: 0; height: auto; } .item.active .qode_slide-svg-holder svg{ -webkit-animation: fade 0.4s 1 cubic-bezier(0.500, 0.110, 0.805, 0.320); -moz-animation: fade 0.4s 1 cubic-bezier(0.500, 0.110, 0.805, 0.320); -o-animation: fade 0.4s 1 cubic-bezier(0.500, 0.110, 0.805, 0.320); animation: fade 0.4s 1 cubic-bezier(0.500, 0.110, 0.805, 0.320); opacity: 1; } .carousel-inner .active .slider_content .thumb{ -webkit-animation: rotate 1s 1 ease-out; -moz-animation: rotate 1s 1 ease-out; -o-animation: rotate 1s 1 ease-out; animation: rotate 1s 1 ease-out; opacity: 1; filter: alpha(opacity = 100); } .carousel-inner .active .slider_content .thumb.fade{ -webkit-animation: fade 1s 1 ease-out; -moz-animation: fade 1s 1 ease-out; -o-animation: fade 1s 1 ease-out; animation: fade 1s 1 ease-out; } .carousel-inner .slider_content .thumb img{ max-height: 100%; } .carousel-inner .slider_content .text{ text-align: center; opacity: 0; filter: alpha(opacity = 0); position: relative; display: inline-block; width: 100%; margin: 10px 0px 10px 0px; -webkit-transform: translateZ(0px); -moz-transform: translateZ(0px); -ms-transform: translateZ(0px); -o-transform: translateZ(0px); transform: translateZ(0px); } .carousel-inner .active .slider_content .text { -webkit-animation: text-from-bottom 1.5s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000); -moz-animation: text-from-bottom 1.5s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000); -o-animation: text-from-bottom 1.5s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000); animation: text-from-bottom 1.5s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000); opacity: 1; filter: alpha(opacity = 100); } /* one by one element animation - start */ .carousel-inner .slider_content .text.one_by_one{ -webkit-animation: none; -moz-animation: none; -o-animation: none; animation: none; opacity: 1; } .carousel-inner .slider_content .text.one_by_one h2, .carousel-inner .slider_content .text.one_by_one h4, .carousel-inner .slider_content .text.one_by_one .separator, .carousel-inner .slider_content .text.one_by_one p, .carousel-inner .slider_content .text.one_by_one a.qbutton, .carousel-inner .slider_content .text.one_by_one .slide_anchor_holder{ opacity: 0; filter: alpha(opacity = 0); position: relative; top: 70px; } .carousel-inner .active .slider_content .text.one_by_one h2, .carousel-inner .active .slider_content .text.one_by_one h4, .carousel-inner .active .slider_content .text.one_by_one .separator, .carousel-inner .active .slider_content .text.one_by_one p, .carousel-inner .active .slider_content .text.one_by_one a.qbutton, .carousel-inner .active .slider_content .text.one_by_one .slide_anchor_holder{ -webkit-animation: text-from-bottom-one-by-one 1.2s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000) 0s; -moz-animation: text-from-bottom-one-by-one 1.2s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000) 0s; -o-animation: text-from-bottom-one-by-one 1.2s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000) 0s; animation: text-from-bottom-one-by-one 1.2s 1 cubic-bezier(0.165, 0.840, 0.440, 1.000) 0s; -webkit-animation-fill-mode: both; -moz-animation-fill-mode: both; -ms-animation-fill-mode: both; -o-animation-fill-mode: both; animation-fill-mode: both; /*top: 0px;*/ opacity: 1; filter: alpha(opacity = 100); } /* without separator and subtitle above - start */ .carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.no_separator h2{ animation-delay:0.15s; -webkit-animation-delay:0.15s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.no_separator p{ animation-delay:0.3s; -webkit-animation-delay:0.3s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.no_separator a.qbutton{ animation-delay:0.45s; -webkit-animation-delay:0.45s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.no_separator .slide_anchor_holder { animation-delay: 0.6s; -webkit-animation-delay: 0.6s; } /* without separator and subtitle above - end */ /* with separator and subtitle above - start */ .carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator h2{ animation-delay:0.15s; -webkit-animation-delay:0.15s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator .separator{ animation-delay:0.3s; -webkit-animation-delay:0.3s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator p{ animation-delay:0.45s; -webkit-animation-delay:0.45s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator a.qbutton{ animation-delay:0.6s; -webkit-animation-delay:0.6s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_above_title.has_separator .slide_anchor_holder { animation-delay: 0.75s; -webkit-animation-delay: 0.75s; } /* with separator and subtitle above - end */ /* without separator and subtitle bellow - start */ .carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.no_separator h4{ animation-delay:0.15s; -webkit-animation-delay:0.15s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.no_separator p{ animation-delay:0.3s; -webkit-animation-delay:0.3s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.no_separator a.qbutton{ animation-delay:0.45s; -webkit-animation-delay:0.45s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.no_separator .slide_anchor_holder { animation-delay: 0.6s; -webkit-animation-delay: 0.6s; } /* without separator and subtitle bellow - end */ /* with separator and subtitle bellow - start */ .carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator h4{ animation-delay:0.15s; -webkit-animation-delay:0.15s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator .separator{ animation-delay:0.3s; -webkit-animation-delay:0.3s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator p{ animation-delay:0.45s; -webkit-animation-delay:0.45s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator a.qbutton{ animation-delay:0.6s; -webkit-animation-delay:0.6s; } .carousel-inner .active .slider_content .text.one_by_one.subtitle_bellow_title.has_separator .slide_anchor_holder { animation-delay: 0.75s; -webkit-animation-delay: 0.75s; } /* with separator and subtitle bellow - end */ /* without separator and no subtitle - start */ .carousel-inner .active .slider_content .text.one_by_one.no_subtitle.no_separator p{ animation-delay:0.2s; -webkit-animation-delay:0.2s; } .carousel-inner .active .slider_content .text.one_by_one.no_subtitle.no_separator a.qbutton{ animation-delay:0.4s; -webkit-animation-delay:0.4s; } .carousel-inner .active .slider_content .text.one_by_one.no_subtitle.no_separator .slide_anchor_holder { animation-delay: 0.6s; -webkit-animation-delay: 0.6s; } /* without separator and no subtitle - end */ /* with separator and no subtitle - start */ .carousel-inner .active .slider_content .text.one_by_one.no_subtitle.has_separator .separator{ animation-delay:0.15s; -webkit-animation-delay:0.15s; } .carousel-inner .active .slider_content .text.one_by_one.no_subtitle.has_separator p{ animation-delay:0.3s; -webkit-animation-delay:0.3s; } .carousel-inner .active .slider_content .text.one_by_one.no_subtitle.has_separator a.qbutton{ animation-delay:0.45s; -webkit-animation-delay:0.45s; } .carousel-inner .active .slider_content .text.one_by_one.no_subtitle.has_separator .slide_anchor_holder { animation-delay: 0.6s; -webkit-animation-delay: 0.6s; } /* with separator and no subtitle - end */ /* one by one element animation - end */ .carousel-inner .slider_content .text .qbutton { margin: 10px 0px 0px 0px; } .carousel-inner .item.dark .slider_content .text .qbutton { border-color: #303030; background-color: #303030; color: #fff; } .carousel-inner .item.dark .slider_content .text .qbutton:hover { background-color: transparent; color: #303030; } .carousel-inner .item.dark .slider_content .text .qbutton.white{ background-color: transparent; color: #303030; } .carousel-inner .item.dark .slider_content .text .qbutton.white:hover{ background-color: #303030; color: #fff !important; border-color: #303030; } .carousel-inner .slider_content .text .qbutton.white{ margin: 10px 0 0 10px; } .carousel-inner h2 { margin: 10px 0 20px 0; font-size: 45px; line-height: 1.071428571428571em; /* 48px / 45px */ } .carousel-inner h2.with_title_border { margin: 20px 0 30px 0; } .carousel-inner h2.with_title_border span { display: inline-block; padding: 0.3em 1.1em; } .carousel-inner h2, .carousel-inner .q_slide_subtitle { font-weight: 600; color: #fff; text-align: center; padding: 0px; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); } .carousel-inner h2.with_background_color span { padding: 10px; } .carousel-inner .q_slide_subtitle { font-size: 26px; letter-spacing: 1px; } .carousel-inner .q_slide_subtitle span { font-size: 1em; margin-bottom: 13px; display: inline-block; } .carousel-inner .q_slide_subtitle.with_background_color span { padding: 10px; margin-bottom: 12px; } .carousel-inner p { color: #fff; text-align: center; font-size: 21px; line-height: 1.363157894736842em; /* 29px / 21px */ font-weight: 400; margin: 10px 0px 15px 0px; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); } .carousel-inner .dark h2, .carousel-inner .dark .q_slide_subtitle, .carousel-inner .dark p{ color: #000; } .carousel-inner .left .text, .carousel-inner .left h2, .carousel-inner .left .q_slide_subtitle, .carousel-inner .left p{ text-align: left; } .carousel-inner .right .text, .carousel-inner .right h2, .carousel-inner .right .q_slide_subtitle, .carousel-inner .right p{ text-align: right; } .carousel-inner { left: 0 !important; position: fixed; overflow: hidden; width: 100%; z-index: 1; transform: translate(0px, 0px); -ms-transform: translate(0px, 0px); -moz-transform: translate(0px, 0px); -webkit-transform: translate(0px, 0px); -o-transform: translate(0px, 0px); -webkit-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -moz-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -o-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); -ms-transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); transition: left 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1), margin 0.33s cubic-bezier(0.694, 0.0482, 0.335, 1); } .carousel-inner.relative_position{ position: relative; } .carousel-inner .item img { display: inline-block !important; } .touch .carousel-inner .item { background-position: center 0px !important; } .carousel-inner .item .image{ position: absolute; top: 0px; left: 0px; background-position: center 0px; background-repeat: no-repeat; background-size: cover; width: 100%; height: 100%; } /* animate image - start */ @media only screen and (min-width: 1000px){ .carousel-inner .item.animate_image.zoom_center .image{ position: absolute; top: 0%; left: 0%; background-position: center center; background-repeat: no-repeat; background-size: cover; width: 100%; height: 110%; -webkit-backface-visibility: hidden; /* to prevent glittering on slide change */ backface-visibility: hidden; } .carousel-inner .item.animate_image.zoom_top_left .image, .carousel-inner .item.animate_image.zoom_top_right .image, .carousel-inner .item.animate_image.zoom_bottom_left .image, .carousel-inner .item.animate_image.zoom_bottom_right .image{ position: absolute; top: -12%; left: -12%; background-position: center center; background-repeat: no-repeat; background-size: cover; width: 125%; height: 125%; -webkit-backface-visibility: hidden; /* to prevent glittering on slide change */ backface-visibility: hidden; } } @media only screen and (max-width: 1000px){ .carousel-inner .item.animate_image.zoom_center .image, .carousel-inner .item.animate_image.zoom_top_left .image, .carousel-inner .item.animate_image.zoom_top_right .image, .carousel-inner .item.animate_image.zoom_bottom_left .image, .carousel-inner .item.animate_image.zoom_bottom_right .image{ transform: none !important; -webkit-transform: none !important; } } /* animate image - end */ .carousel-inner .item .image img{ display: none !important; width: 0px; height: 0px; } .carousel-inner .item .image_pattern { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-position: 0 0; background-repeat: repeat; z-index: 2; } .carousel-control { top: 0px; width: 23%; color: #303030; font-size: 13px; height: 100%; background: none; text-shadow: none; position: absolute; border-radius: 0; -webkit-border-radius: 0; -moz-border-radius: 0; border: none; z-index: 2 !important; margin: 0px; outline: none; cursor: pointer; -webkit-transition: color 0.6s ease-in-out, opacity 0.3s ease-in-out; -moz-transition: color 0.6s ease-in-out, opacity 0.3s ease-in-out; -o-transition: color 0.6s ease-in-out, opacity 0.3s ease-in-out; -ms-transform: color 0.6s ease-in-out, opacity 0.3s ease-in-out; transition: color 0.6s ease-in-out, opacity 0.3s ease-in-out; } .carousel-control.right { right: 0; left: auto; } .carousel-control:hover{ color: #303030; opacity: 1 !important; } .carousel-control.dark, .carousel-control.dark:hover{ color: #fff; } .carousel-control .prev_nav, .carousel-control .next_nav{ height: 54px; width: 54px; border: 2px solid #fff; line-height: 54px; font-size: 14px; position: absolute; top: 50%; margin-top: -27px; text-align: center; z-index: 10; -webkit-transition: opacity 0.3s ease 0s; -moz-transition: opacity 0.3s ease 0s; -o-transition: opacity 0.3s ease 0s; transition: opacity 0.3s ease-in-out; opacity: 0; -webkit-border-radius: 56px; -moz-border-radius: 56px; -ms-border-radius: 56px; -o-border-radius: 56px; border-radius: 56px; } @media only screen and (max-width: 1000px){ .carousel-control .prev_nav, .carousel-control .next_nav { margin-top: -27px !important; } } .carousel-control i{ font-size:30px; color: #fff; line-height: 54px; } .carousel-control.dark .prev_nav i, .carousel-control.dark .next_nav i{ color: #000; } .carousel-control.light .prev_nav i, .carousel-control.light .next_nav i{ color: #fff; } .carousel-control.dark .prev_nav, .carousel-control.dark .next_nav{ border-color: #000; } .carousel-control.light .prev_nav, .carousel-control.light .next_nav{ border-color: #fff; } .carousel-control .prev_nav{ left: 23px; } .q_slider:hover .carousel-control .prev_nav{ opacity: 1; } .carousel-control .next_nav{ right: 23px; } .q_slider:hover .carousel-control .next_nav{ opacity: 1; } .q_slider:hover .carousel-control .next_nav:hover, .q_slider:hover .carousel-control .prev_nav:hover{ opacity: 1; } .carousel-control .thumb_holder{ width: 150px; display: block; position: absolute; margin: -20px 0px 0px 0px; top: 50%; z-index: 9; } .carousel-control .thumb_holder .thumb_top{ background-color: #fff; display: block; position: relative; } .carousel-control.dark .thumb_holder .thumb_top{ background-color: #000; } .carousel-control.left .thumb_holder .thumb_top{ -webkit-border-radius:0px 3px 0px 0px; -moz-border-radius:0px 3px 0px 0px; -ms-border-radius: 0px 3px 0px 0px; border-radius:0px 3px 0px 0px; } .carousel-control.right .thumb_holder .thumb_top{ -webkit-border-radius:3px 0px 0px 0px; -moz-border-radius:3px 0px 0px 0px; -ms-border-radius: 3px 0px 0px 0px; border-radius:3px 0px 0px 0px; } .carousel-control.left .thumb_holder{ left: -100%; -webkit-transition: left 0.2s ease-in-out; -moz-transition: left 0.2s ease-in-out; -o-transition: left 0.2s ease-in-out; -ms-transform: left 0.2s ease-in-out; transition: left 0.2s ease-in-out; -webkit-border-radius:0px 3px 3px 0px; -moz-border-radius:0px 3px 3px 0px; -ms-border-radius: 0px 3px 3px 0px; border-radius:0px 3px 3px 0px; display: none; } .slider_thumbs .carousel-control.left:hover .thumb_holder{ left: 0px; } .in_progress.slider_thumbs .carousel-control.left .thumb_holder{ left: -100% !important; } .carousel-control.right .thumb_holder{ right: -100%; -webkit-transition: right 0.2s ease-in-out; -moz-transition: right 0.2s ease-in-out; -o-transition: right 0.2s ease-in-out; -ms-transform: right 0.2s ease-in-out; transition: right 0.2s ease-in-out; -webkit-border-radius:3px 0px 0px 3px; -moz-border-radius:3px 0px 0px 3px; -ms-border-radius: 3px 0px 0px 3px; border-radius:3px 0px 0px 3px; display: none; } .slider_thumbs .carousel-control.right:hover .thumb_holder{ right: 0px; } .in_progress.slider_thumbs .carousel-control.right .thumb_holder{ right: -100% !important; } .carousel-control.left .arrow_left{ float: left; height: 40px; line-height: 40px; padding: 0px 0px 0px 15px; } .carousel-control.left .numbers{ float: right; height: 40px; line-height: 40px; padding: 0px 20px 0px 0px; } .carousel-control.right .arrow_right{ float: right; height: 40px; line-height: 40px; padding: 0px 15px 0px 0px; } .carousel-control.right .numbers{ float: left; height: 40px; line-height: 40px; padding: 0px 0px 0px 20px; } .carousel-control .img_outer{ top: 0px; clear: both; width: 150px; height: 47px; position: relative; display: block; overflow: hidden; margin: 0px 0px -2px 0px; } .carousel-control .img{ top: -47px; width: 150px; height: 47px; position: relative; display: block; overflow: hidden; } .in_progress .carousel-control:hover .img{ top: -47px !important; } .carousel-control:hover .img{ top: 0px; -webkit-transition: top 0.2s ease-in-out 0.2s; -moz-transition: top 0.2s ease-in-out 0.2s; -o-transition: top 0.2s ease-in-out 0.2s; -ms-transform: top 0.2s ease-in-out 0.2s; transition: top 0.2s ease-in-out 0.2s; } .carousel-control.right .img{ float: right; } .carousel-control .img img, .carousel-control .img .video{ position: absolute; top: 0px; left: 0px; z-index: 2; } .carousel-control .img .video{ left: -1px; } .carousel-control .img .old{ z-index: 1; } @media only screen and (max-width: 1300px){ .carousel-control { width: 15%; } } @media only screen and (max-width: 1000px){ .carousel-control{ width: 10%; } .carousel-control .prev_nav{ left: 0px; opacity: 1; } .carousel-control.left .thumb_holder{ display: none; } .carousel-control .next_nav{ right: 0px; opacity: 1; } .carousel-control.right .thumb_holder{ display: none; } } .touch .carousel-control{ width: 10%; } .touch .carousel-control.left{ background-position: 30px center !important; } .touch .carousel-control.left .thumb_holder{ display: none; } .touch .carousel-control.right{ background-position: 100% center !important; } .touch .carousel-control.right .thumb_holder{ display: none; } /* old way responsiveness - start */ @media (max-width: 1200px) { .carousel:not(.advanced_responsiveness) .carousel-inner h2 { margin-top: 0; } .carousel:not(.advanced_responsiveness) .carousel-inner h2 span { font-size: 0.625em !important; line-height: 1.4em !important; } .carousel:not(.advanced_responsiveness) .carousel-inner .q_slide_subtitle span { font-size: 0.8em; } .carousel:not(.advanced_responsiveness) .carousel-inner h2 { line-height: inherit !important; } } @media (max-width: 1024px) { .carousel:not(.advanced_responsiveness) .carousel-inner{ position: relative; } .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton { font-size: 12px; line-height: 31px; height: 31px; } .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton i{ margin: 0px 0px 0px 20px; } } @media only screen and (max-height: 850px){ .full_screen:not(.advanced_responsiveness) .carousel-inner .slider_content{ height: 35%; } } @media only screen and (max-width: 800px) { .carousel:not(.advanced_responsiveness) .carousel .carousel-inner .slider_content_outer { display: table; } .carousel:not(.advanced_responsiveness) .carousel-inner .slider_content .thumb { height: auto; } .carousel:not(.advanced_responsiveness) .carousel .carousel-inner .slider_content { display: table-cell; vertical-align: middle; position: static; top: 0 !important; left: 0 !important; } .carousel:not(.advanced_responsiveness) .carousel-inner h2.large span { font-size: .425em!important; } } @media (max-width: 768px) { .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton { font-size: 11px; line-height: 27px; height: 27px; } .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton i { margin: 0px 0px 0px 17px; } .carousel:not(.advanced_responsiveness) .carousel-inner h2.with_title_border span { padding: .3em 0.8em; } .carousel:not(.advanced_responsiveness) .carousel-control.left { left: 0; } .carousel:not(.advanced_responsiveness) .carousel-control.right { right: 0; } } @media only screen and (max-height: 600px){ .full_screen:not(.advanced_responsiveness) .carousel-inner .slider_content{ height: 25%; } } @media (max-width: 567px) { .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton{ font-size: 10px; line-height: 23px; height: 23px; } .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton i{ margin: 0px 0px 0px 14px; } .carousel:not(.advanced_responsiveness) .carousel-inner p { line-height: 1.4em !important; } .carousel:not(.advanced_responsiveness) .carousel-control { display: none; } .carousel:not(.advanced_responsiveness) .carousel-inner h2.large span { font-size: .38em !important; } .carousel:not(.advanced_responsiveness) .carousel-inner h2 span { font-size: .525em !important; } } @media (max-width: 480px) { .carousel:not(.advanced_responsiveness) .carousel-inner h2.large span { font-size: .3em !important; } } @media (max-width: 320px) { .carousel:not(.advanced_responsiveness) .carousel-inner h2.large span { font-size: 0.2em !important; } .carousel:not(.advanced_responsiveness) .carousel-inner h2 span { font-size: 0.4em !important; line-height: 1em !important; } .carousel:not(.advanced_responsiveness) .carousel-inner p span { font-size: 60% !important; } .carousel:not(.advanced_responsiveness) .carousel-inner p { line-height: 1em !important; } .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton{ font-size: 9px; line-height: 20px; height: 20px; } .carousel:not(.advanced_responsiveness) .carousel-inner .qbutton i{ margin: 0px 0px 0px 10px; } .carousel:not(.advanced_responsiveness) .carousel-inner h2.with_title_border { margin: 0 0 10px; } } /* old way responsiveness - end */ /* advanced responsiveness - start */ @media (max-width: 1200px) { .carousel.advanced_responsiveness .carousel-inner h2 { margin-top: 0; } } @media (max-width: 1000px) { .carousel.advanced_responsiveness .carousel-inner{ position: relative; } .carousel.advanced_responsiveness .carousel-inner > .item { padding-top: 0px !important; } .carousel.advanced_responsiveness .carousel-control .prev_nav, .carousel.advanced_responsiveness .carousel-control .next_nav{ margin-top: 0px !important; } .carousel.advanced_responsiveness .carousel .carousel-inner .slider_content_outer { display: table; box-sizing: border-box; display: table; padding: 0 5px; } .carousel.advanced_responsiveness .carousel .carousel-inner .slider_content .thumb { height: auto; } .carousel.advanced_responsiveness .carousel .carousel-inner .slider_content { display: table-cell; vertical-align: middle; position: static; top: 0 !important; left: 0 !important; } .carousel.advanced_responsiveness .carousel .carousel-inner .graphic_content{ text-align: center; } } @media (max-width: 567px) { .carousel.advanced_responsiveness .carousel-control { display: none; } } @media (max-width: 350px) { .carousel.advanced_responsiveness .carousel .carousel-inner .slider_content_outer { width: 100% !important; } } /* advanced responsiveness - end */ .carousel-indicators li{ background-color: #fff; opacity: 0.4; margin: 0px 3px; -webkit-transition: all 0.6s ease-in-out; -moz-transition: all 0.6s ease-in-out; -o-transition: all 0.6s ease-in-out; -ms-transform: all 0.6s ease-in-out; transition: all 0.6s ease-in-out; } .carousel-indicators.dark li{ background-color: #000; } .carousel-indicators .active{ opacity: 1; margin: 0px 3px; } @-webkit-keyframes text-from-bottom { 0% { -webkit-transform: translate(0, 15%); opacity: 0; } 50% { -webkit-transform: translate(0, 15%); opacity: 0; } 100% { -webkit-transform: translate(0, 0); opacity: 1; } } @-moz-keyframes text-from-bottom { 0% { -moz-transform: translate(0, 15%); opacity: 0; } 50% { -moz-transform: translate(0, 15%); opacity: 0; } 100% { -moz-transform: translate(0, 0); opacity: 1; } } @-o-keyframes text-from-bottom { 0% { -o-transform: translate(0, 15%); opacity: 0; } 50% { -o-transform: translate(0, 15%); opacity: 0; } 100% { -o-transform: translate(0, 0); opacity: 1; } } @keyframes text-from-bottom { 0% { transform: translate(0, 15%); opacity: 0; } 50% { transform: translate(0, 15%); opacity: 0; } 100% { transform: translate(0, 0); opacity: 1; } } @-webkit-keyframes rotate { 0% { -webkit-transform: perspective(600px) rotateX(90deg) scale(.5); opacity: 0; } 50% { -webkit-transform: perspective(600px) rotateX(90deg) scale(.5); opacity: 0; } 100% { -webkit-transform: perspective(600px) rotateX(0deg) scale(1); opacity: 1; } } @-moz-keyframes rotate { 0% { -moz-transform: perspective(600px) rotateX(90deg) scale(.5); opacity: 0; } 50% { -moz-transform: perspective(600px) rotateX(90deg) scale(.5); opacity: 0; } 100% { -moz-transform: perspective(600px) rotateX(0deg) scale(1); opacity: 1; } } @-o-keyframes rotate { 0% { -o-transform: perspective(600px) rotateX(90deg) scale(.5); opacity: 0.2; } 50% { -o-transform: perspective(600px) rotateX(90deg) scale(.5); opacity: 0.2; } 100% { -o-transform: perspective(600px) rotateX(0deg) scale(1); opacity: 1; } } @keyframes rotate { 0% { transform: perspective(600px) rotateX(90deg) scale(.5); opacity: 0; } 50% { transform: perspective(600px) rotateX(90deg) scale(.5); opacity: 0; } 100% { transform: perspective(600px) rotateX(0deg) scale(1); opacity: 1; } } @-webkit-keyframes fade { 0% { opacity: 0; } 50% { opacity: 0; } 100% { opacity: 1; } } @-moz-keyframes fade { 0% { opacity: 0; } 50% { opacity: 0; } 100% { opacity: 1; } } @-o-keyframes fade { 0% { opacity: 0; } 50% { opacity: 0; } 100% { opacity: 1; } } @keyframes fade { 0% { opacity: 0; } 50% { opacity: 0; } 100% { opacity: 1; } } @-webkit-keyframes text-from-bottom-one-by-one { 0% { top: 70px; opacity: 0; } 50% { top: 45px; opacity: 0; } 100% { top: 0px; opacity: 1; } } @-moz-keyframes text-from-bottom-one-by-one { 0% { top: 70px; opacity: 0; } 50% { top: 45px; opacity: 0; } 100% { top: 0px; opacity: 1; } } @-o-keyframes text-from-bottom-one-by-one { 0% { top: 70px; opacity: 0; } 50% { top: 45px; opacity: 0; } 100% { top: 0px; opacity: 1; } } @keyframes text-from-bottom-one-by-one { 0% { top: 70px; opacity: 0; } 50% { top: 45px; opacity: 0; } 100% { top: 0px; opacity: 1; } } .carousel .video .mobile-video-image { background-position: center center; background-repeat: no-repeat; background-size: cover; display: none; height: 100%; left: 0; position: absolute; top: 0; width: 100%; z-index: 10; } .carousel .video .video-overlay { height: 3000px; left: 0; opacity: 0; position: absolute; top: 0; width: 100%; z-index: 11; } .carousel .video .video-overlay.active { background-image: url("img/pixel-video.png"); background-position: 0px 0px; background-repeat: repeat; opacity: 1; } .carousel .video .video-overlay img{ display: none !important; } .carousel .video .video-wrap { top: 0px; left: 0px; overflow: hidden; position: absolute; width: 100%; z-index: 10; } .carousel .video .video-wrap .mejs-poster { background-size: cover !important; -moz-background-size: cover !important; -webkit-background-size: cover !important; -o-background-size: cover !important; } .carousel .video .video-wrap .mejs-container .mejs-controls { display: none !important; } .carousel .video .video-wrap .mejs-controls .mejs-button button:focus { outline: none !important; } .carousel .video .video-wrap .mejs-controls .mejs-time-rail .mejs-time-loaded { background-color: rgba(255, 255, 255, 0.18) !important; } .carousel .video .video-wrap .mejs-container { background-color: transparent !important; background-image: none !important; height: auto !important; } .carousel .video .video-wrap .mejs-mediaelement{ background: none !important; border: 0px !important; } .carousel .video .video-wrap .mejs-container .mejs-poster img { max-width: none !important; width: 100% !important; } .carousel .video .video-wrap .mejs-controls button { opacity: 0.8; } .carousel .video .video-wrap .mejs-controls button:hover, .mejs-controls .mejs-fullscreen-button:hover button { opacity: 1!important;} .carousel .video .video-wrap .mejs-controls .mejs-time-rail .mejs-time-total { background: #1f1f1f none repeat scroll 0 0 !important; } .carousel .video .video-wrap .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current { background: transparent !important; } .carousel .item .text .separator { margin-top: 40px; margin-bottom: 40px; width: 68%; } .carousel .item .left .text .separator{ margin-left: 0; } .carousel .item .right .text .separator{ margin-right: 0; } /*** Custom cursor for slider navigation ***/ .q_slider .has_custom_cursor .prev_nav, .q_slider .has_custom_cursor .next_nav, .no-touch .q_slider .has_custom_cursor .carousel-indicators{ display:none !important; } /*** Custom cursor for slider navigation end ***/ /* ==== Carousel Custom - End ==== */ /* ==== Portfolio Slider, Portfolio Single Slider - Start ==== */ .flex-container a:active, .flexslider a:active, .flex-container a:focus, .flexslider a:focus, .portfolio_slider .flex-container a:active, .portfolio_slider .flexslider a:active, .portfolio_slider .flex-container a:focus, .portfolio_slider .flexslider a:focus, .qode_carousels .flex-container a:active, .qode_carousels a:active, .qode_carousels .flex-container a:focus, .qode_carousels a:focus{ outline: 0; } .portfolio_slides, .slides, .flex-control-nav, .flex-direction-nav, .caroufredsel-direction-nav { margin: 0; padding: 0; list-style: none; } .flexslider .slides>li{ background-color: transparent; display: none; position: relative; margin: 0; } .caroufredsel_wrapper { cursor: grab!important; cursor: -moz-grab!important; cursor: -webkit-grab!important; margin: 0px!important; } .portfolio_slider .portfolio_slides, .qode_carousels .slides{ opacity: 0; } .portfolio_slider .portfolio_slides>li, .qode_carousels .slides>li{ background-color: transparent; position: relative; margin: 0; float: left; } .qode_carousels .slides>li{ margin: 0 2px 0 0; } .flexslider .slides img, .portfolio_slider .portfolio_slides img, .qode_carousels .slides img{ width: 100%; display: block; } .gallery_frame{ width: 100%; height:100%; position: absolute; top: 0; text-align: center; } .wpb_flexslider.flexslider.have_frame{ width: 645px; margin: 0 auto; overflow: visible; } .frame_holder > .wpb_wrapper { padding: 34px 0 102px 0; position: relative; } .frame_holder.frame_holder2 > .wpb_wrapper{ padding: 48px 0 75px 0; } .slides:after, .portfolio_slides:after{ content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; } html[xmlns] .slides, html[xmlns] .portfolio_slides{ display: block; } * html .slides, * html .portfolio_slides{ height: 1%; } .no-js .slides>li:first-child, .no-js .portfolio_slides>li:first-child{ display: block; } .flexslider, .portfolio_slider { margin: 0 0 60px; position: relative; zoom: 1; } .wpb_flexslider.flexslider{ overflow:hidden; } .portfolio_slider { margin: 0; width: 100.2%; } .boxed .portfolio_slider{ margin: 0 -25px 60px; overflow: hidden; } .flex-viewport, .portfolio_slider .flex-viewport{ max-height: 2000px; -webkit-transition: all 1s ease; -moz-transition: all 1s ease; transition: all 1s ease; } .loading .flex-viewport{ max-height: 300px; } .flexslider .slides, .portfolio_slider .portfolio_slides, .qode_carousels .slides{ zoom: 1; } .flexslider ul{ padding:0; } .portfolio_slider .flex-direction-nav, .flexslider .flex-direction-nav{ *height: 0; } .flex-direction-nav a, .caroufredsel-direction-nav a { width: 42px; height: 42px; line-height: 42px; margin: -23px 0 0; display: block; position: absolute; top: 50%; z-index: 10; cursor: pointer; text-align: center; -webkit-transition: all .3s ease 0s; -moz-transition: all .3s ease 0s; -o-transition: all .3s ease 0s; color: #8a8a8a; background-color:transparent; text-align:center; z-index: 200; border:2px solid #fff; } .flex-direction-nav a { -webkit-box-sizing: initial; -moz-box-sizing: initial; box-sizing: initial; } .flexslider:hover .flex-direction-nav a.flex-prev:hover, .flexslider:hover .flex-direction-nav a.flex-next:hover, .portfolio_slider:hover .flex-direction-nav a.flex-prev:hover, .portfolio_slider:hover .flex-direction-nav a.flex-next:hover, .portfolio_slider:hover .caroufredsel-direction-nav a.caroufredsel-next:hover, .portfolio_slider:hover .caroufredsel-direction-nav a.caroufredsel-prev:hover, .blog_slider:hover .caroufredsel-direction-nav a.caroufredsel-next:hover, .blog_slider:hover .caroufredsel-direction-nav a.caroufredsel-prev:hover { background-color: #fff; } .flexslider:hover .flex-direction-nav a.flex-prev:hover i, .flexslider:hover .flex-direction-nav a.flex-next:hover i, .portfolio_slider:hover .flex-direction-nav a.flex-prev:hover i, .portfolio_slider:hover .flex-direction-nav a.flex-next:hover i, .portfolio_slider:hover .caroufredsel-direction-nav a.caroufredsel-next:hover i, .portfolio_slider:hover .caroufredsel-direction-nav a.caroufredsel-prev:hover i, .blog_slider:hover .caroufredsel-direction-nav a.caroufredsel-next:hover i, .blog_slider:hover .caroufredsel-direction-nav a.caroufredsel-prev:hover i { color:#8a8a8a; } .flex-direction-nav a i, .caroufredsel-direction-nav a i { line-height: 42px; color: #fff; font-size: 22px; } .have_frame .flex-direction-nav a i{ display: none; } .flexslider .flex-next, .portfolio_slider .flex-next, .portfolio_slider .caroufredsel-next { right: 15px; -webkit-border-radius:2em; -moz-border-radius:2em; -ms-border-radius: 2em; border-radius:2em; } .have_frame.flexslider .flex-next{ right: -80px; -webkit-border-radius:0; -moz-border-radius:0; -ms-border-radius: 0; border-radius:0; background-image: url('img/frame_arrow_right.png'); background-repeat: no-repeat; background-position: center center; width: 25px; height: 67px; border: none; } .have_frame.flexslider .flex-next:hover{ background-color: transparent !important; background-image: url('img/frame_arrow_right_hover.png'); } .flexslider .flex-prev, .portfolio_slider .flex-prev, .portfolio_slider .caroufredsel-prev { left: 15px; -webkit-border-radius:2em; -moz-border-radius:2em; -ms-border-radius: 2em; border-radius:2em; } .have_frame.flexslider .flex-prev{ left: -80px; -webkit-border-radius:0; -moz-border-radius:0; -ms-border-radius: 0; border-radius:0; background-image: url('img/frame_arrow_left.png'); background-repeat: no-repeat; background-position: center center; width: 25px; height: 67px; border: none; } .have_frame.flexslider .flex-prev:hover{ background-color: transparent !important;; background-image: url('img/frame_arrow_left_hover.png'); } @media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { .have_frame.flexslider .flex-prev{ background-image: url('img/frame_arrow_left@1_5x.png'); -o-background-size: 25px 67px; -webkit-background-size: 25px 67px; -moz-background-size: 25px 67px; background-size: 25px 67px; } .have_frame.flexslider .flex-prev:hover{ background-image: url('img/frame_arrow_left_hover@1_5x.png'); } .have_frame.flexslider .flex-next{ background-image: url('img/frame_arrow_right@1_5x.png'); -o-background-size: 25px 67px; -webkit-background-size: 25px 67px; -moz-background-size: 25px 67px; background-size: 25px 67px; } .have_frame.flexslider .flex-next:hover{ background-image: url('img/frame_arrow_right_hover@1_5x.png'); } } @media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { .have_frame.flexslider .flex-prev{ background-image: url('img/frame_arrow_left@2x.png'); -o-background-size: 25px 67px; -webkit-background-size: 25px 67px; -moz-background-size: 25px 67px; background-size: 25px 67px; } .have_frame.flexslider .flex-prev:hover{ background-image: url('img/frame_arrow_left_hover@2x.png'); } .have_frame.flexslider .flex-next{ background-image: url('img/frame_arrow_right@2x.png'); -o-background-size: 25px 67px; -webkit-background-size: 25px 67px; -moz-background-size: 25px 67px; background-size: 25px 67px; } .have_frame.flexslider .flex-next:hover{ background-image: url('img/frame_arrow_right_hover@2x.png'); } } .flex-direction-nav .flex-disabled{ cursor: default; } /* ==== Portfolio Slider, Portfolio Single Slider - End ==== */ /* ==== Qode Carousel Slider - Start ==== */ .qode_carousels .slides>li .first_image_holder, .qode_carousels .slides>li .second_image_holder{ display: block; position: relative; width: 100%; opacity: 1; -webkit-transition: opacity 0.4s ease-in-out; -ms-transition: opacity 0.4s ease-in-out; -moz-transition: opacity 0.4s ease-in-out; -o-transition: opacity 0.4s ease-in-out; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; } .qode_carousels .slides>li .second_image_holder{ position: absolute; top: 0; left: 0; } .qode_carousels .slides>li .second_image_holder, .qode_carousels .slides > li .carousel_item_holder:hover .first_image_holder.has_hover_image{ opacity: 0; } .qode_carousels .slides > li .carousel_item_holder:hover .second_image_holder.has_hover_image{ opacity: 1; } .qode_carousels{ padding: 0; position: relative; display: block; zoom: 1; } .qode_carousels_holder.two_rows .slides > li .carousel_item_holder { margin-bottom: 15px; position: relative; } .qode_carousels .flex-direction-nav { height: 0; display: none !important; } /* Control Nav */ .qode_carousels .flex-control-nav{ width: 100%; text-align: center; position: absolute; bottom: -60px; } .qode_carousels .flex-control-nav li{ margin: 0 3px; display: inline-block; zoom: 1; display: inline; } .qode_carousels .flex-control-paging li a{ width: 9px; height: 9px; display: inline-block; border: 1px solid #eaeaea; background-color: #fff; cursor: pointer; text-indent: -9999px; -webkit-border-radius: 20px; -moz-border-radius: 20px; -o-border-radius: 20px; border-radius: 20px; } .qode_carousels .flex-control-paging li a.flex-active{ background-color: #1abc9c; cursor: default; border: none; } .qode_carousels.gray .flex-control-paging li a.flex-active { cursor: default; } /* ==== Qode Carousel Slider - End ==== */ .wpb_row, .wpb_content_element, ul.wpb_thumbnails-fluid > li, .last_toggle_el_margin, .wpb_button { margin-bottom: 0 !important; } /* ========================================================================== Clients styles ========================================================================== */ .qode_clients .qode_client_holder { float: left; text-align: center; margin-bottom: 35px; } .qode_clients.two_columns .qode_client_holder { width: 50%; } .qode_clients.three_columns .qode_client_holder { width: 33.33%; } .qode_clients.four_columns .qode_client_holder { width: 25%; } .qode_clients.five_columns .qode_client_holder { width: 20%; } .qode_clients.six_columns .qode_client_holder { width: 16.66666666666667%; } .qode_clients .qode_client_holder_inner { position: relative; margin: 0 20px; } .qode_clients .qode_client_holder_inner:before, .qode_clients .qode_client_holder_inner:after { display: block; content: ""; position: absolute; } .qode_clients .qode_client_holder_inner:before { height: 100%; right: -20px; width: 1px; border-right: 1px solid #eaeaea; } .qode_clients .qode_client_holder_inner:after { width: 100%; bottom: -20px; height: 1px; border-bottom: 1px solid #eaeaea; } .qode_clients .qode_client_holder.border-bottom-none .qode_client_holder_inner:after { border-bottom: 0; } .qode_clients.two_columns .qode_client_holder:nth-child(2n) .qode_client_holder_inner:before, .qode_clients.three_columns .qode_client_holder:nth-child(3n) .qode_client_holder_inner:before, .qode_clients.four_columns .qode_client_holder:nth-child(4n) .qode_client_holder_inner:before, .qode_clients.five_columns .qode_client_holder:nth-child(5n) .qode_client_holder_inner:before, .qode_clients.six_columns .qode_client_holder:nth-child(6n) .qode_client_holder_inner:before { border-right-width: 0; } .qode_clients .qode_client_holder a { display: inline-block; vertical-align: middle; max-width: 100%; line-height: 0; -webkit-transition: opacity 0.6s ease-out; -moz-transition: opacity 0.6s ease-out; -o-transition: opacity 0.6s ease-out; -ms-transform: opacity 0.6s ease-out; transition: opacity 0.6s ease-out; } .qode_clients .qode_client_holder a:hover { opacity: 0.4; } /* ========================================================================== Animated icon with text styles ========================================================================== */ .animated_icons_with_text .animated_icon_with_text_holder { float: left; text-align: center; } .animated_icons_with_text.two_columns .animated_icon_with_text_holder { width: 50%; } .animated_icons_with_text.three_columns .animated_icon_with_text_holder { width: 33.33%; } .animated_icons_with_text.four_columns .animated_icon_with_text_holder { width: 25%; } .animated_icons_with_text.five_columns .animated_icon_with_text_holder { width: 20%; } .animated_icons_with_text.six_columns .animated_icon_with_text_holder { width: 16.66666666666667%; } .animated_icons_with_text .animated_icon_with_text_inner { position: relative; padding: 0px 20px; height: 85px; } .animated_icons_with_text .animated_icon_with_text_inner:before, .animated_icons_with_text .animated_icon_with_text_inner:after { display: block; content: ""; position: absolute; } .animated_icons_with_text .animated_icon_with_text_inner:before { height: 100%; right: 0px; width: 1px; border-right: 1px solid #f5f5f5; } .animated_icons_with_text .animated_icon_with_text_inner:after { width: 100%; bottom: 0px; height: 1px; border-bottom: 1px solid #f5f5f5; } .animated_icons_with_text .animated_icon_with_text_holder.border-bottom-none .animated_icon_with_text_inner:after { border-bottom: none; } .animated_icons_with_text.two_columns .animated_icon_with_text_holder:nth-child(2n) .animated_icon_with_text_inner:before, .animated_icons_with_text.three_columns .animated_icon_with_text_holder:nth-child(3n) .animated_icon_with_text_inner:before, .animated_icons_with_text.four_columns .animated_icon_with_text_holder:nth-child(4n) .animated_icon_with_text_inner:before, .animated_icons_with_text.five_columns .animated_icon_with_text_holder:nth-child(5n) .animated_icon_with_text_inner:before, .animated_icons_with_text.six_columns .animated_icon_with_text_holder:nth-child(6n) .animated_icon_with_text_inner:before { border-right-width: 0; } .animated_icon_holder{ height: 100%; padding:0 0 0 15px; display: block; width: 81px; float: left; position: relative; } .animated_icon{ height: 100%; width: 100%; position: relative; } .animated_icon_inner span{ -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; backface-visibility: hidden; backface-visibility: hidden; left: 0px; position: absolute; top: 0; -webkit-transition: 200ms ease-in; -moz-transition: 200ms ease-in; -o-transition: 200ms ease-in; transition: 200ms ease-in; } .animated_icon_inner span.animated_icon_back{ -webkit-transform: rotateY(-180deg); -moz-transform: rotateY(-180deg); -ms-transform: rotateY(-180deg); -o-transform: rotateY(-180deg); transform: rotateY(-180deg); } .animated_icon_with_text_holder:hover .animated_icon_inner span.animated_icon_back{ -webkit-transform: rotateY(0); -moz-transform: rotateY(0); -ms-transform: rotateY(0); -o-transform: rotateY(0); transform: rotateY(0); } .animated_icon_with_text_holder:hover .animated_icon_inner span { -webkit-transform: rotateY(180deg); -moz-transform: rotateY(180deg); -ms-transform: rotateY(180deg); -o-transform: rotateY(180deg); transform: rotateY(180deg); } .animated_icon_inner{ height: 81px; width: 100%; position: absolute; left:0px; top: 50%; margin: -41px 0 0 0; } .animated_icon_inner i { width: 77px; height: 77px; line-height: 77px; background: transparent; -o-border-radius: 100px; -moz-border-radius: 100px; -webkit-border-radius: 100px; border-radius: 100px; margin: 0; border: 2px solid #c0c0c0; color: #c0c0c0; font-size:35px; } .animated_icon_inner span.animated_icon_back i{ background-color: #1abc9c; color:#fff; border-color: #1abc9c; } .animated_icon_with_text_holder .animated_text_holder { text-align: left; width: 100%; height: 100%; } .animated_icon_with_text_holder .animated_text_holder_wrap{ display: block; padding: 0 0 0 116px; height: 100%; } .animated_icon_with_text_holder .animated_text_holder_wrap_inner{ width: 100%; height: 100%; position: relative; } .animated_text_holder_inner{ position: absolute; left: 0; width: 100%; top: 0; overflow: hidden; height: 100%; } .animated_icon_with_text_holder .animated_title, .animated_icon_with_text_holder .animated_text{ display: table; position: absolute; overflow: hidden; width: 100%; height: 100%; } .animated_icon_with_text_holder .animated_title_inner, .animated_icon_with_text_holder .animated_text p{ display: table-cell; vertical-align: middle; } .animated_icon_with_text_holder .animated_title, .animated_icon_with_text_holder .animated_title_inner, .animated_icon_with_text_holder .animated_text, .animated_icon_with_text_holder .animated_text p{ -webkit-transition: 200ms ease-in; -moz-transition: 200ms ease-in; -o-transition: 200ms ease-in; transition: 200ms ease-in; } .animated_icon_with_text_holder .animated_text { -webkit-transform: translateY(-100%); -moz-transform: translateY(-100%); -ms-transform: translateY(-100%); -o-transform: translateY(-100%); transform: translateY(-100%); -webkit-transform: translate3d(0, -100%, 0); -moz-transform: translate3d(0, -100%, 0); -ms-transform: translate3d(0, -100%, 0); -o-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); } .animated_icon_with_text_holder .animated_text p{ -webkit-transform: translateY(100%); -moz-transform: translateY(100%); -ms-transform: translateY(100%); -o-transform: translateY(100%); transform: translateY(100%); -webkit-transform: translate3d(0, 100%, 0); -moz-transform: translate3d(0, 100%, 0); -ms-transform: translate3d(0, 100%, 0); -o-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); } .animated_icon_with_text_holder:hover .animated_text, .animated_icon_with_text_holder:hover .animated_text p{ -webkit-transform: translateY(0); -moz-transform: translateY(0); -ms-transform: translateY(0); -o-transform: translateY(0); transform: translateY(0); -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); -o-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); -webkit-transition: 350ms ease-out; -moz-transition: 350ms ease-out; -o-transition: 350ms ease-out; transition: 350ms ease-out; } .animated_icon_with_text_holder:hover .animated_title_inner{ -webkit-transform: translateY(-100%); -moz-transform: translateY(-100%); -ms-transform: translateY(-100%); -o-transform: translateY(-100%); transform: translateY(-100%); -webkit-transform: translate3d(0, -100%, 0); -moz-transform: translate3d(0, -100%, 0); -ms-transform: translate3d(0, -100%, 0); -o-transform: translate3d(0, -100%, 0); transform: translate3d(0, -100%, 0); -webkit-transition: 350ms ease-out; -moz-transition: 350ms ease-out; -o-transition: 350ms ease-out; transition: 350ms ease-out; } .animated_icon_with_text_holder:hover .animated_title{ -webkit-transform: translateY(100%); -moz-transform: translateY(100%); -ms-transform: translateY(100%); -o-transform: translateY(100%); transform: translateY(100%); -webkit-transform: translate3d(0, 100%, 0); -moz-transform: translate3d(0, 100%, 0); -ms-transform: translate3d(0, 100%, 0); -o-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); -webkit-transition: 350ms ease-out; -moz-transition: 350ms ease-out; -o-transition: 350ms ease-out; transition: 350ms ease-out; } /* ========================================================================== Service table shorcode start styles ========================================================================== */ .service_table_holder{ display: block; position: relative; border-color: #f6f6f6; border-width: 1px; border-style: none; } .service_table_inner{ display: block; position: relative; list-style: none; margin: 0; padding: 0; } .service_table_inner ul{ padding: 0 !important; } .service_table_inner li{ display: block; margin: 0; padding: 0; list-style: none; text-align: center; border-bottom: 1px solid #f6f6f6; } .service_table_inner > li{ background-color: #fff; } .service_table_inner li li{ padding: 9px 20px; } .service_table_inner li:last-child{ border-bottom: 0; } .service_table_inner li.service_table_title_holder{ display: block; position: relative; padding: 31px 20px 20px; background-color: #fff; border: none; } .service_table_inner li.service_table_title_holder i{ color: #1abc9c; } .service_table_title_inner{ position: relative; display: table; width: 100%; height: 100%; text-align: center; } .service_table_title_inner2{ display: table-cell; width: 100%; height: 100%; padding: 20px 20px 25px; vertical-align: middle; } .service_table_inner li.service_table_title_holder.background_image_type{ background-color: transparent !important; border: 0 !important; padding: 0; background-position: center center; background-repeat: no-repeat; background-size: cover; } .service_table_inner li.service_table_title_holder.background_color_type .service_table_title_inner2{ padding: 0; } .service_table_title_holder .service_title{ display: block; } .service_table_title_holder i{ display: block; line-height: 1em; padding: 33px 0 0; } /* ========================================================================== Service table shorcode end styles ========================================================================== */ /* ========================================================================== End Clients styles ========================================================================== */ .header_top_bottom_holder{ position: relative; } .qode_search_form{ background: none repeat scroll 0 0 #262626; color: #fff; margin: 0; overflow: hidden; width: 100%; height: 0px; position: absolute; top:0; left:0; } .qode_search_form .qode_icon_in_search { color: #959595; font-size: 13px; display: inline-block; padding: 0px 0px 0px 45px; float: left; line-height: 50px; } .qode_search_form input, .qode_search_form input:focus{ background-color: #262626; border: medium none; box-shadow: none; color: #959595; display: inline-block; font-size: 13px; line-height: 20px; height: 20px; margin: 15px 0px; width: 90%; padding: 0px 45px 0px 10px; font-family: inherit; outline: none; outline-offset:0px; -webkit-appearance: none; border-radius: 0; float: left; } .qode_search_form input:focus{ outline-offset: 0px !important; } ::-webkit-input-placeholder, :-moz-placeholder, ::-moz-placeholder, :-ms-input-placeholder{ color: #959595; margin: 10px 0px 0px 0px; } @media only screen and (max-width: 1200px){ .qode_search_form input{ width: 80%; } } @media only screen and (max-width: 768px){ .qode_search_form input{ width: 70%; } } @media only screen and (max-width: 500px){ .qode_search_form input{ width: 65%; } } .qode_search_form .container_inner{ position: relative; } .qode_search_form .container .qode_icon_in_search { padding: 0px; } .qode_search_form .container input{ width: 90%; padding: 0px 0px 0px 10px; } .qode_search_form input[type="submit"] { border: 0 none; clip: rect(0px, 0px, 0px, 0px); height: 1px; margin: -1px; padding: 0; position: absolute; width: 1px; visibility: hidden; } .qode_search_form .qode_search_close{ color: #959595; font-size: 13px; position: absolute; line-height: 50px; height: 50px; top: 0px; right: 45px; } .qode_search_form .container .qode_search_close{ right: 0px; } /* slide from header bottom */ .qode_search_form_2{ background: none repeat scroll 0 0 #f1f1f1; color: #fff; margin: 0; overflow: hidden; width: 100%; height: 100px; bottom: 0; position: absolute; transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53); -webkit-transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53); -moz-transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53); left:0; opacity: 1; } .qode_search_form_2.animated{ transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53), opacity 0s ease 0s; -webkit-transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53), opacity 0s ease 0s; -moz-transition: bottom 0.35s cubic-bezier(.55,.085,.68,.53), opacity 0s ease 0s; left:0; opacity: 1; } .qode_search_form_2 .container{ z-index:auto; } .qode_search_form_2 .form_holder_outer { display: table; height: 100px; width: 100%; } .qode_search_form_2 .form_holder { display: table-cell; vertical-align: middle; position:relative; } .qode_search_form_2.animated .form_holder_outer { height: 100px; } .qode_search_form_2 .container_inner .form_holder { padding: 0px; } .qode_search_form_2 .form_holder { padding: 0 45px; } .qode_search_form_2 input, .qode_search_form_2 input:focus{ background-color: transparent; border: medium none; box-shadow: none; color: #9d9d9d; font-size: 15px; font-weight: 600; display: inline-block; vertical-align: middle; width: 90%; padding: 0; font-family: inherit; outline: none; outline-offset:0px; -webkit-appearance: none; border-radius: 0; text-transform: uppercase; } .qode_search_form_2 input:focus{ outline-offset: 0px !important; } .qode_search_form_2 .qode_search_submit { width: auto; cursor: pointer; font-size:50px; position:absolute; right: 45px; top: 50%; -moz-transform: translateY(-50%); -webkit-transform: translateY(-50%); transform: translateY(-50%); transition: color 0.4s ease; -webkit-transition: color 0.4s ease; -moz-transition: color 0.4s ease; color: #696969; padding: 0 0 0 1px; } .qode_search_form_2 .container_inner .qode_search_submit { right:0; } .qode_search_form_2 .qode_search_submit:hover{ color:#1abc9c } .qode_search_form_2.disabled .qode_search_submit, .qode_search_form_2.disabled .qode_search_submit:hover { cursor:default; color:#959595; } /* search covers header */ .qode_search_form_3{ display: none; color: #fff; position: absolute; top: 0; left: 0; width: 100%; z-index: 115; background:#fff; } .admin-bar .qode_search_form_3 { padding-top: 33px; } .qode_search_form_3 .form_holder_outer{ display: table; width: 100%; height:100%; } .qode_search_form_3 .form_holder{ display: table-cell; vertical-align: middle; padding:0px 45px; position:relative; } .qode_search_form_3 .container_inner .form_holder{ padding: 0px; } .qode_search_form_3 input, .qode_search_form_3 input:focus{ background-color: transparent; border: medium none; box-shadow: none; color: #9d9d9d; font-size: 15px; font-weight: 600; display: inline-block; width: 90%; padding:0; font-family: inherit; outline: none; outline-offset:0px; -webkit-appearance: none; border-radius: 0; float: left; text-transform: uppercase; margin: 0; } .qode_search_form_3 input:focus{ outline-offset: 0px !important; } .qode_search_form_3 input[type="submit"]{ border: 0 none; clip: rect(0px,0px,0px,0px); height: 1px; margin: -1px; padding: 0; position: absolute; width: 1px; visibility: hidden; } .qode_search_form_3 .qode_search_close{ font-size: 34px; position: absolute; right: 45px; top:50%; -webkit-transform: translateY(-50%); -moz-transform: translateY(-50%); -ms-transform: translateY(-50%); -o-transform: translateY(-50%); transform: translateY(-50%); line-height:1em; } .qode_search_form_3 .container_inner .qode_search_close{ right: 0; } .qode_search_form_3 .qode_search_close a{ color: #9d9d9d; display: inline-block; } .qode_search_form_3 .qode_search_close a:hover{ color: #1abc9c; } ::-webkit-input-placeholder, :-moz-placeholder, ::-moz-placeholder, :-ms-input-placeholder{ color: #959595; margin: 10px 0px 0px 0px; } .qode_search_form_3 .qode_search_close a i{ vertical-align: top; } /* insert end */ /*----------------------FULLSCREEN SEARCH style start--------------------------*/ .side_menu_button{ position:relative; } .fullscreen_search_holder{ position:fixed; top:0; left:0; width:100%; height:100%; z-index:105; opacity:0; } .fullscreen_search_table{ display: table; width:100%; height:100%; } .fullscreen_search_cell{ display: table-cell; vertical-align: middle; width:100%; height:100%; text-align:center; } .fullscreen_search_holder .search_label{ font-size:30px; line-height:1em; color: #a1a1a1; vertical-align:bottom; font-family:inherit; margin-right:5px; } .fullscreen_search_holder .field_holder{ width:30%; display:inline-block; vertical-align:bottom; position:relative; border-bottom:1px solid #a1a1a1; } .fullscreen_search_holder .field_holder .line{ position:absolute; bottom:-1px; left:0; height:1px; width:0; background-color: #1abc9c; -webkit-transition: width 0.4s ease; transition: width 0.4s ease; } .fullscreen_search_holder .search_field{ width:100%; border-left:none; border-top:none; border-right:none; border-bottom:none; background:transparent; outline:none; height:100%; font-size:25px; color: #9d9d9d; line-height:1em; position:relative; font-family: inherit; } .fullscreen_search_holder .search_submit{ border:none; background:transparent; outline:none; width: auto; cursor: pointer; font-family: 'FontAwesome'; font-size:20px; line-height:1em; -webkit-transition: color 0.2s ease; transition: color 0.2s ease; color: #a1a1a1; } .fullscreen_search_holder .search_submit:hover{ color: #1abc9c; } .fullscreen_search_holder .search_close_holder{ float:right; } .fullscreen_search_holder .close_container{ position:absolute; left:0; top:0; width:100%; } .fullscreen_search_holder .close_container a{ opacity:0; visibility:hidden; -webkit-transition: opacity 0.2s ease, color 0.2s ease; transition: opacity 0.2s ease, color 0.2s ease; } .fullscreen_search_holder .close_container a:hover{ color: #1abc9c; } .fullscreen_search_holder .close_container .search_close_holder{ margin-right: 45px; } .fullscreen_search_holder .close_container .container_inner .search_close_holder{ margin-right: 0px; } /*---Fulscreen search FROM CIRCLE style---*/ .fullscreen_search_overlay{ position:absolute; width:2000px; height:2000px; margin-top:-1000px; margin-left:-1000px; top:50%; left:0; border-radius:100%; opacity:0; z-index:99; -ms-transform-origin: 50%; -webkit-transform-origin: 50%; transform-origin: 50%; -ms-transform: scale(0); -webkit-transform: scale(0); -moz-transform: scale(0); -o-transform: scale(0); transform: scale(0); background-color: rgba(255,255,255,0.98); -webkit-backface-visibility: hidden; backface-visibility: hidden; -ms-transition: -ms-transform 0.6s cubic-bezier(0.4,0,0.2,1), opacity 0.6s cubic-bezier(0.4,0,0.2,1); -webkit-transition: -webkit-transform 0.6s cubic-bezier(0.4,0,0.2,1), opacity 0.6s cubic-bezier(0.4,0,0.2,1); transition: transform 0.6s cubic-bezier(0.4,0,0.2,1), opacity 0.6s cubic-bezier(0.4,0,0.2,1); } .fullscreen_search_overlay.animate{ -ms-transform: scale(3); -moz-transform: scale(3); -o-transform: scale(3); -webkit-transform: scale(3); transform: scale(3); opacity:1; } .fullscreen_search_holder.from_circle{ -webkit-transition: opacity 0.3s ease; transition: opacity 0.3s ease; display:none; opacity:0; visibility:visible; z-index:111; } /*---Fulscreen search FADE style---*/ .fullscreen_search_holder.fade{ visibility: hidden; -webkit-backface-visibility: hidden; backface-visibility: hidden; opacity: 0; background-color:rgba(255,255,255,0.98); z-index:111; } .search_fade_out .fullscreen_search_holder.fade{ -webkit-animation: search_fade_out .25s linear both; animation: search_fade_out .25s linear both ; } .search_fade_in .fullscreen_search_holder.fade.animate{ -webkit-animation: search_fade_in .25s linear both; animation: search_fade_in .25s linear both; } .fullscreen_search_holder.fade.animate .fullscreen_search_close{ opacity:1; visibility:visible; } @-webkit-keyframes search_fade_out { 0%{ opacity:1; visibility: visible; } 100%{ opacity:0; visibility: hidden; } } @keyframes search_fade_out{ 0%{ opacity:1; visibility: visible; } 100% { opacity:0; visibility: hidden; } } @-webkit-keyframes search_fade_in { 0% { opacity:0; visibility: hidden; } 100% { opacity:1; visibility: visible; } } @keyframes search_fade_in{ 0%{ opacity:0; visibility: hidden; } 100%{ opacity:1; visibility: visible; } } /*----------------Search styles end---------------------*/ /****** Cover Boxes start style *******/ .cover_boxes{ position: relative; overflow: hidden; } .cover_boxes ul{ list-style: none; margin: 0px -20px 0px 0px; padding: 0px; width: 200%; } .cover_boxes ul li{ float: left; margin-right: 20px; overflow: hidden; position: relative; width: 265px; -webkit-transition: all 0.5s ease 0s; -moz-transition: all 0.5s ease 0s; -o-transition: all 0.5s ease 0s; transition: all 0.5s ease 0s; } .cover_boxes ul li.act{ width: 530px; } .cover_boxes ul li .box{ width: 530px; } .cover_boxes ul li .box .thumb { display: inline-block; float: left; margin-right: 20px; position: relative; z-index:10; width: 265px; } .cover_boxes ul li .box .thumb img{ display: block; position: relative; max-width: 100%; } .cover_boxes ul li .box .box_content{ bottom: 0px; left: 285px; position: absolute; padding: 0px 0px 0px 0px; width: 245px; z-index:9; top: 0; } .cover_boxes ul li .box h3{ margin: 0px 0px 18px 0px; } .cover_boxes ul li .box .qbutton, .cover_boxes ul li .box h5{ margin: 20px 0px 0px 0px; } /********* Cover Boxes end style **********/ /* ========================================================================== Qode circles styles ========================================================================== */ .q_circles_holder{ position: relative; display: inline-block; width: 100%; clear: both; list-style: none; margin: 0; padding: 0; } .q_circles_holder:before{ position: absolute; left: 80px; display: block; width: 85%; height: 0; border-top: 1px solid #eaeaea; content: ""; } .q_circles_holder.three_columns:before{ top: 115px; } .q_circles_holder.four_columns:before{ top: 90px; } .q_circles_holder.five_columns:before{ top: 82px; } .q_circles_holder.no_line:before{ display: none; border: 0; height: 0; width: 0; } .q_circles_holder .q_circle_outer{ position: relative; float: left; padding: 0; margin: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -o-box-sizing: border-box; } .q_circles_holder.three_columns .q_circle_outer{ width: 33.3%; } .q_circles_holder.four_columns .q_circle_outer{ width: 25%; } .q_circles_holder.five_columns .q_circle_outer{ width: 20%; } .q_circles_holder .q_circle_inner{ position: relative; display: table; vertical-align: middle; text-align: center; margin: 0 auto; } .q_circles_holder.three_columns .q_circle_inner{ width: 230px; height: 230px; } .q_circles_holder.four_columns .q_circle_inner{ width: 180px; height: 180px; } .q_circles_holder.five_columns .q_circle_inner{ width: 161px; height: 161px; } .q_circles_holder.five_columns .q_circle_inner.big_border{ width: 177px; height: 177px; } .q_circles_holder .q_circle_inner2 { position: relative; display: table-cell; width: 100%; height: 100%; vertical-align: middle; text-align: center; background-color: #e3e3e3; border: 1px solid #f0f0f0; border-radius: 1000px; -webkit-border-radius: 1000px; -moz-border-radius: 1000px; -o-border-radius: 1000px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -o-box-sizing: border-box; overflow: hidden; } .q_circles_holder .q_circle_inner2 img { display: block; width: 100%; border-radius: 1000px; -webkit-border-radius: 1000px; -moz-border-radius: 1000px; -o-border-radius: 1000px; } .q_circles_holder .q_circle_inner2 i, .q_circles_holder .q_circle_inner2, .q_circles_holder .q_circle_inner2 .q_text_in_circle { -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; } .q_circles_holder .q_circle_inner2 i{ color: #b9b9b9; } .q_circles_holder .q_circle_inner2:hover { background-color: #1abc9c !important; border-color: #1abc9c !important; } .q_circles_holder .q_circle_inner2:hover i, .q_circles_holder .q_circle_inner2:hover .q_text_in_circle{ color: #fff !important; } .q_circles_holder .q_circle_text_holder{ display: block; text-align: center; margin: 36px 0 0; padding:0 10px; } .q_circles_holder .q_circle_text_holder .q_circle_text{ display: block; margin: 7px 0 0; } /* ========================================================================== End of Qode circles styles ========================================================================== */ /******** Content Menu - Start ********/ nav.content_menu{ position: relative; text-align: left; display: block; z-index: 1001; background-color: #ffffff; -webkit-transform: translateZ(0px); width: 100%; -webkit-transition: left .33s cubic-bezier(0.694,0.0482,0.335,1); -moz-transition: left .33s cubic-bezier(0.694,0.0482,0.335,1); -o-transition: left .33s cubic-bezier(0.694,0.0482,0.335,1); -ms-transform: left .33s cubic-bezier(0.694,0.0482,0.335,1); } .full_width nav.content_menu.fixed { left: 0; } .right_side_menu_opened .full_width nav.content_menu.fixed { left: -270px; } .container_inner nav.content_menu{ width: 1100px; } .container_inner nav.content_menu.fixed{ -moz-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.11); -webkit-box-shadow: 0 4px 4px -4px rgba(0,0,0,0.11); box-shadow: 0 4px 4px -4px rgba(0,0,0,0.11); } nav.content_menu ul{ width: 1100px; margin: 0px auto; position: relative; list-style: none outside none; padding: 0px; text-align: center; -webkit-backface-visibility: hidden; } nav.content_menu ul li{ display: inline-block; padding: 0px; text-align: center; position: relative; -webkit-backface-visibility: hidden; } nav.content_menu ul li .arrow{ background-image: url("img/content_menu_arrow.png"); background-position: 0px 0px; background-repeat: no-repeat; display: none; width: 11px; height: 7px; position: absolute; left: 50%; margin: -1px 0px 0px -5px; -webkit-backface-visibility: hidden; } nav.content_menu.fixed ul li.active .arrow{ display: none; } nav.content_menu ul li a{ color: #c3c3c3; font-size: 13px; text-decoration: none; display: inline-block; position: relative; cursor: pointer; padding: 21px 20px; margin: 0px; } nav.content_menu ul li a span{ display: block; width: 100%; text-transform: uppercase; letter-spacing: 1px; line-height: 18px; padding: 12px 0 0 0; font-weight: 600; } nav.content_menu ul li i{ color: #c3c3c3; margin: 4px 0px 0px 0px; font-size:24px; line-height: 1em; display: block; } nav.content_menu ul li i.undefined{ display: none; } nav.content_menu ul li.active:hover i, nav.content_menu ul li:hover i, nav.content_menu ul li.active:hover a, nav.content_menu ul li:hover a{ color: #1abc9c; } nav.content_menu ul li.active i, nav.content_menu ul li.active a{ color: #303030; } nav.content_menu .nav_select_menu{ display: none; border: 1px solid #eaeaea; } nav.content_menu .nav_select_menu .nav_select_button{ cursor: pointer; display: block; height: 40px; position: relative; width: 40px; line-height: 40px; text-align: center; float: right; } nav.content_menu .nav_select_menu ul{ display: none; border: 0px; width: 100%; position: relative; top: 0px; text-align: left; padding: 0px 0px 10px 0px; float: left; z-index: 100; zoom:1; } nav.content_menu .nav_select_menu ul li{ display: block; border: 0px; float: none; padding: 0px; margin: 0px; text-align: left; position: relative; -webkit-backface-visibility: hidden; } nav.content_menu .nav_select_menu ul li a{ line-height: 30px; } nav.content_menu .nav_select_menu ul li a i{ width: 12px; text-align: center; } .boxed nav.content_menu.fixed{ padding: 0px; width: 1100px; } /******** Content Menu - End ********/ /******** Visual Composer - Start ********/ .section_inner_margin, .parallax_section_inner_margin { margin-left: -15px; margin-right: -15px; } /******** Visual Composer - End ********/ /* ========================================================================== Contact form 7 styles ========================================================================== */ .wpcf7 form.wpcf7-form p { margin-bottom: 20px; } input.wpcf7-form-control.wpcf7-text, input.wpcf7-form-control.wpcf7-number, input.wpcf7-form-control.wpcf7-date, textarea.wpcf7-form-control.wpcf7-textarea, select.wpcf7-form-control.wpcf7-select { width: 100%; } input.wpcf7-form-control.wpcf7-text, input.wpcf7-form-control.wpcf7-number, input.wpcf7-form-control.wpcf7-date, textarea.wpcf7-form-control.wpcf7-textarea, select.wpcf7-form-control.wpcf7-select, input.wpcf7-form-control.wpcf7-quiz { margin: 5px 0 0; padding: 15px; border: 0; outline: 0; resize: none; font-size: 13px; line-height: 17px; background-color: #fff; color: #818181; font-family: 'Raleway'; font-weight: 400; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } input.wpcf7-form-control.wpcf7-quiz { margin-left: 15px; } span.wpcf7-form-control-wrap .wpcf7-form-control.wpcf7-checkbox input[type="checkbox"], span.wpcf7-form-control-wrap .wpcf7-form-control.wpcf7-radio input[type="radio"] { position: relative; top: 2px; } span.wpcf7-form-control-wrap .wpcf7-form-control.wpcf7-checkbox input[type="checkbox"] { margin-left: 5px; } input.wpcf7-form-control.wpcf7-submit { position: relative; display: inline-block; width: auto; height: 39px; line-height: 36px; margin: 0; padding: 0px 23px; font-size: 13px; font-weight: 700; font-family: 'Raleway', sans-serif; text-align: left; text-decoration: none; cursor: pointer; white-space: nowrap; outline: none; font-style: normal; text-transform: uppercase; letter-spacing: 1px; -o-border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; text-shadow: none; background-color: transparent; -webkit-transition: all 0.1s linear; -moz-transition: all 0.1s linear; -ms-transition: all 0.1s linear; -o-transition: all 0.1s linear; transition: all 0.1s linear; -webkit-box-sizing: initial; -moz-box-sizing: initial; box-sizing: initial; } input.wpcf7-form-control.wpcf7-submit[disabled] { color: #818181; border: 2px solid #818181; cursor: not-allowed; } input.wpcf7-form-control.wpcf7-submit:not([disabled]) { border: 2px solid #303030; color: #303030; } input.wpcf7-form-control.wpcf7-submit:not([disabled]):hover { background-color: #1abc9c; border-color: #1abc9c; color: #fff; text-decoration: none; } input.wpcf7-form-control.wpcf7-range { width: 100%; } div.wpcf7-response-output { position: relative; padding: 17px 30px 17px 55px; color: #fff; text-transform: uppercase; font-weight: 500; margin-left: 0; margin-right: 0; font-weight: 500; font-size: 15px; text-transform: uppercase; letter-spacing: 1px; border: none; } div.wpcf7-response-output:before { font-family: 'FontAwesome', sans-serif; width: 20px; height: 20px; display: inline-block; color: #fff; position: absolute; left: 25px; } div.wpcf7-response-output.wpcf7-mail-sent-ok { background-color: #1abc9c; } div.wpcf7-response-output.wpcf7-mail-sent-ok:before { content: "\f087"; } div.wpcf7-response-output.wpcf7-validation-errors { background-color: #f1c40f; } div.wpcf7-response-output.wpcf7-validation-errors:before { content: "\f12a"; } .two_columns_form_without_space, .two_columns_form_with_space{ display: table; } .two_columns_form_with_space input.wpcf7-form-control.wpcf7-text, .two_columns_form_without_space input.wpcf7-form-control.wpcf7-text{ margin: 0; } .two_columns_form_without_space .column_left { display: table-cell; vertical-align: top; } .two_columns_form_without_space .column_right { display: table-cell; width: 1%; text-align: left; vertical-align: top; } .two_columns_form_with_space .column_left { display: table-cell; vertical-align: top; padding-right: 5px; } .two_columns_form_with_space .column_right { display: table-cell; width: 1%; vertical-align: top; padding-left: 5px; } /* ========================================================================== End Contact form 7 styles ========================================================================== */ /* ========================================================================== Gravity forms styles ========================================================================== */ body .gform_wrapper .gform_fields .gfield{ margin: 0 0 20px 0; } body .gform_wrapper .gf_progressbar, body .gform_wrapper .gf_progressbar_wrapper, body .gform_wrapper .top_label input.large, body .gform_wrapper .top_label select.large, body .gform_wrapper .top_label textarea.textarea { /*width: 100%;*/ } body .gform_wrapper .gf_progressbar_percentage, body .gform_wrapper .gf_step, body .gform_wrapper .gf_step span.gf_step_number, body .gform_wrapper .gfield_description, body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper textarea, body .gform_wrapper input[type="button"], body .gform_wrapper input[type="submit"], body .gform_wrapper input[type="reset"], body .gform_wrapper .chzn-container .chzn-single, body .gform_wrapper .chzn-container-single .chzn-single, body .gform_wrapper select { font-family: 'Raleway', sans-serif; } body .gform_wrapper .gf_progressbar, body .gform_wrapper .chzn-container .chzn-single, body .gform_wrapper .chzn-container-single .chzn-single, body .gform_wrapper .chzn-container-single .chzn-drop, body .gform_wrapper .chzn-container-multi .chzn-drop, body .gform_wrapper .chzn-container-active .chzn-single, body .gform_wrapper .chzn-container-active .chzn-choices { -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; } body .gform_wrapper .gf_progressbar, body .gform_wrapper .chzn-container .chzn-single, body .gform_wrapper .chzn-container-single .chzn-single, body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper textarea, body .gform_wrapper .chzn-container-single .chzn-single div, body .gform_wrapper .chzn-container-single .chzn-single b, body .gform_wrapper .chzn-container .chzn-drop, body .gform_wrapper .chzn-choices, body .gform_wrapper .chzn-container-multi .chzn-choices, body .gform_wrapper li.gfield.gfield_error, body .gform_wrapper li.gfield.gfield_error.gfield_contains_required.gfield_creditcard_warning, body .gform_wrapper select{ border: 0; } body .gform_wrapper .gf_progressbar, body .gform_wrapper .chzn-container .chzn-single, body .gform_wrapper .chzn-container-single .chzn-single{ background-image: none; } body .gform_wrapper .top_label .gfield_label, body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper textarea, body .gform_wrapper .ginput_left input:focus+label, body .gform_wrapper .ginput_right input:focus+label, body .gform_wrapper .ginput_full input:focus+label, body .gform_wrapper table.gfield_list thead th { font-weight: 400; } body .gform_wrapper .charleft{ margin-top: 0; } body .gform_wrapper .gfield_description { padding: 5px 0 0 0; } body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper textarea, body .gform_wrapper select, body .gform_wrapper.gf_browser_chrome .ginput_complex select, body .gform_wrapper.gf_browser_chrome .ginput_complex .ginput_right select { padding: 15px; outline: 0; resize: none; box-sizing: border-box; } body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper textarea, body .gform_wrapper input[type="button"], body .gform_wrapper input[type="submit"], body .gform_wrapper input[type="reset"], body .gform_wrapper .chzn-container .chzn-single, body .gform_wrapper .chzn-container-single .chzn-single, body .gform_wrapper select{ font-size: 13px; } body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper textarea, body .gform_wrapper .chzn-container .chzn-single, body .gform_wrapper .chzn-container-single .chzn-single { line-height: 17px; } body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper textarea, body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper .chzn-container .chzn-single, body .gform_wrapper .chzn-container-single .chzn-single, body .gform_wrapper .chzn-container-single .chzn-single b { background-color: #ffffff; } body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper textarea, body .gform_wrapper .chzn-container-single .chzn-single span, body .gform_wrapper select{ color: #818181; } body .gform_wrapper input[type=text], body .gform_wrapper input[type=url], body .gform_wrapper input[type=email], body .gform_wrapper input[type=tel], body .gform_wrapper input[type=number], body .gform_wrapper input[type=password], body .gform_wrapper textarea, body .gform_wrapper .chzn-container, body .gform_wrapper select{ margin: 5px 0 0; } body .gform_wrapper input[type="button"], body .gform_wrapper input[type="submit"], body .gform_wrapper input[type="reset"]{ position: relative; display: inline-block; width: auto; height: 39px; line-height: 36px; margin: 0; padding: 0px 23px; border: 2px solid #303030; font-weight: 700; text-align: left; color: #303030; text-decoration: none; cursor: pointer; white-space: nowrap; outline: none; font-style: normal; text-transform: uppercase; letter-spacing: 1px; -o-border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; text-shadow: none; background-color: transparent; -webkit-transition: all 0.1s linear; -moz-transition: all 0.1s linear; -ms-transition: all 0.1s linear; -o-transition: all 0.1s linear; transition: all 0.1s linear; } body .gform_wrapper input[type="button"]:hover, body .gform_wrapper input[type="submit"]:hover, body .gform_wrapper input[type="reset"]:hover{ background-color: #1abc9c; border-color: #1abc9c; color: #ffffff; text-decoration: none; } body .gform_wrapper .chzn-container .chzn-single, body .gform_wrapper .chzn-container-single .chzn-single { height: auto; padding: 15px 2%; } body .gform_wrapper .chzn-container-single .chzn-single div b{ background-position: -18px 10px; } body .gform_wrapper .chzn-container-single .chzn-single-with-drop div b{ background-position: -1px 10px; } body .gform_wrapper .chzn-container-single .chzn-search input{ border: 1px solid #aaaaaa; } body .gform_wrapper .chzn-choices{ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ffffff), color-stop(0, #ffffff)) !important; } body .gform_wrapper .chzn-choices .search-field .default{ padding-left: 10%; } body .gform_wrapper .chzn-container-multi .chzn-choices .search-field input { padding: 15px; } body .gform_wrapper div.validation_error, body .gform_wrapper .gform_confirmation_message { position: relative; padding: 17px 30px 17px 30px; color: #fff; text-transform: uppercase; margin-left: 0; margin-right: 0; font-weight: 500; font-size: 15px; text-transform: uppercase; letter-spacing: 1px; border: none; } body .gform_wrapper div.validation_error { background-color: #f1c40f; } body .gform_wrapper .gform_confirmation_message{ background-color: #1abc9c; } body .gform_wrapper .ginput_complex .name_prefix, body .gform_wrapper .ginput_complex .name_suffix, body .gform_wrapper input.ginput_quantity{ width: 60px !important; } body .gform_wrapper .datepicker { width: 105px !important; } body .gform_wrapper .gfield_time_ampm select { min-width: 80px; } body .gform_wrapper .gfield_time_hour{ vertical-align: middle; } body .gform_wrapper .button.gform_button_select_files{ height: 31px; line-height: 24px; padding: 0 9px; font-size: 12px; margin-left: 10px; } /* ========================================================================== End Gravity forms styles ========================================================================== */ /* ========================================================================== Vertical menu styles ========================================================================== */ .vertical_menu_enabled .q_slider, .vertical_menu_enabled .full_width, .vertical_menu_enabled .content .container, .vertical_menu_enabled .title_outer, .vertical_menu_enabled footer{ padding-left: 260px; } .boxed.vertical_menu_enabled .q_slider, .boxed.vertical_menu_enabled .full_width, .boxed.vertical_menu_enabled .content .container, .boxed.vertical_menu_enabled .title_outer, .boxed.vertical_menu_enabled footer{ padding-left: 0px; } .boxed.vertical_menu_enabled, .boxed.vertical_menu_enabled footer.uncover{ padding-left: 260px; } .vertical_menu_enabled .content .title .container{ padding-left: 0px; } .vertical_menu_enabled .content .container, .vertical_menu_enabled .q_slider, .vertical_menu_enabled footer{ width: auto; } aside.vertical_menu_area { position: fixed; width: 260px; top: 0; left: 0; padding:10px 30px; background-color: #fff; height: 100%; z-index: 101; -webkit-backface-visibility:hidden; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -webkit-transition: background-color 0.3s ease; -moz-transition: background-color 0.3s ease; -o-transition: background-color 0.3s ease; -ms-transition: background-color 0.3s ease; transition: background-color 0.3s ease; outline: none; } aside.vertical_menu_area.with_scroll { overflow: hidden; } aside.vertical_menu_area .vertical_menu_area_widget_holder{ font-size:13px; position: relative; } .vertical_menu_enabled.vertical_area_transparent .content{ padding-left: 0px; } .vertical_menu_transparency_on aside.vertical_menu_area.light .vertical_menu_area_widget_holder, .vertical_menu_transparency_on aside.vertical_menu_area.light .widget a, .vertical_menu_transparency_on aside.vertical_menu_area.light .q_social_icon_holder i.simple_social{ color: #fff; } .vertical_menu_transparency_on aside.vertical_menu_area.dark .vertical_menu_area_widget_holder, .vertical_menu_transparency_on aside.vertical_menu_area.dark .widget a, .vertical_menu_transparency_on aside.vertical_menu_area.dark .q_social_icon_holder i.simple_social{ color: #000; } .vertical_menu_enabled header{ display: block; } .vertical_menu_enabled header .header_inner{ display: none; } .vertical_area_background{ position: fixed; width: 260px; height: 100%; background-position: right top; background-repeat: no-repeat; background-size: cover; top: 0px; left: 0px; z-index: 0; -webkit-transition: opacity 0.6s ease; -moz-transition: opacity 0.6s ease; -o-transition: opacity 0.6s ease; -ms-transition: opacity 0.6s ease; transition: opacity 0.6s ease; opacity: 1; } .vertical_logo_wrapper{ z-index: 100; position: relative; } .vertical_logo_wrapper img{ max-width: 100%; position: absolute; top: 0px; left: 0px; -webkit-transition: opacity 0.3s ease; -moz-transition: opacity 0.3s ease; -o-transition: opacity 0.3s ease; -ms-transition: opacity 0.3s ease; transition: opacity 0.3s ease; } .q_logo_vertical img.normal{ position: relative; } .q_logo_vertical img.light, .q_logo_vertical img.dark{ opacity: 0; } .vertical_menu_transparency_on .light .q_logo_vertical img.normal{ opacity:0; } .vertical_menu_transparency_on .light .q_logo_vertical img.light{ opacity:1; } .vertical_menu_transparency_on .light .q_logo_vertical img.dark{ opacity:0; } .vertical_menu_transparency_on .dark .q_logo_vertical img.normal{ opacity:0; } .vertical_menu_transparency_on .dark .q_logo_vertical img.light{ opacity:0; } .vertical_menu_transparency_on .dark .q_logo_vertical img.dark{ opacity:1; } nav.vertical_menu { position: relative; z-index: 101; margin: 45px 0 0 0; } .vertical_menu ul{ list-style: none; } .vertical_menu ul li{ position: relative; } nav.vertical_menu > ul > li > a { position: relative; color: #303030; font-size: 13px; font-weight: 700; letter-spacing: 1px; text-decoration: none; text-transform: uppercase; display: block; position: relative; line-height: 34px; padding: 0 0px; margin: 0; cursor: pointer; -webkit-transition: color 0.3s ease; -moz-transition: color 0.3s ease; -o-transition: color 0.3s ease; -ms-transition: color 0.3s ease; transition: color 0.3s ease; } .vertical_menu_transparency_on .light nav.vertical_menu > ul > li > a{ color: #ffffff; } .vertical_menu_transparency_on .dark nav.vertical_menu > ul > li > a{ color: #000000; } .vertical_menu .second .inner{ position: relative; display: block; padding: 0; z-index: 997; } .vertical_menu_toggle .second .inner_arrow, .vertical_menu_on_click .second .inner_arrow, .vertical_menu_float .second .inner_arrow{ display: none; } .vertical_menu .second .inner > ul > li > a:hover{ color: #303030; } .vertical_menu_toggle .second, .vertical_menu_on_click .second{ margin: 0px; display: none; overflow: hidden; z-index: 10; } .vertical_menu_toggle .second ul ul, .vertical_menu_on_click .second ul ul{ display: none; } nav.vertical_menu_toggle ul li a, nav.vertical_menu_on_click ul li a{ display: block; } nav.vertical_menu_toggle ul li a .line, nav.vertical_menu_on_click ul li a .line{ display: none; } nav.vertical_menu_toggle ul > li.menu-item-has-children > a > .plus, nav.vertical_menu_on_click ul > li.menu-item-has-children > a > .plus, nav.vertical_menu_float ul > li.menu-item-has-children > a > .plus{ float: right; width: 20px; height: 8px; margin: 12px 0 0 0; z-index: 10000; display: block; position: relative; background-image: url('img/vertical_menu_cross.png'); background-repeat: no-repeat; background-position: 100%; -o-background-size: 8px 8px; -webkit-background-size: 8px 8px; -moz-background-size: 8px 8px; background-size: 8px 8px; } nav.vertical_menu_toggle ul li ul > li.menu-item-has-children > a > .plus, nav.vertical_menu_on_click ul li ul > li.menu-item-has-children > a > .plus, nav.vertical_menu_float ul li ul > li.menu-item-has-children > a > .plus{ margin: 5px 0 0 0; } .no-touch nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, .no-touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .no-touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus{ background-image: url('img/vertical_menu_minus.png'); } .touch nav.vertical_menu_toggle ul > li.menu-item-has-children.open > a > .plus, .touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { background-image: url('img/vertical_menu_minus.png'); } nav.vertical_menu_toggle ul li.menu-item-has-children a span, nav.vertical_menu_on_click ul li.menu-item-has-children a span, nav.vertical_menu_float ul li.menu-item-has-children a span{ display: inline-block; max-width: 180px; } .vertical_menu_float .menu-item .second { position: absolute; top: 0; left: calc(100% + 30px); /*because of the padding*/ width: 100%; margin-left: 50px; opacity: 0; background-color: #fff; visibility: hidden; transition: all 0.3s ease-in-out; } .vertical_menu_float .menu-item .second *{ visibility: hidden; transition: visibility 0.3s ease-in-out; } .vertical_menu_float .menu-item .second.vertical_menu_start { margin-left: 0px; opacity: 1; visibility: visible; } .vertical_menu_float .menu-item .second.vertical_menu_start *{ visibility: visible; } .vertical_menu_float .menu-item .second.vertical_menu_start ul li ul, .vertical_menu_float .menu-item .second.vertical_menu_start ul li ul *{ visibility:hidden; } .vertical_menu_float .menu-item .second.vertical_menu_start ul li ul.vertical_submenu_start, .vertical_menu_float .menu-item .second.vertical_menu_start ul li ul.vertical_submenu_start *{ visibility:visible; } .vertical_menu_float .second .inner ul{ width: 100%; } .vertical_menu_float li.narrow .second .inner ul{ /*because of the .narrow styling*/ border: none; background-color: #fff; padding: 0; } .vertical_menu_float .second .inner ul li ul { position: absolute; border:none; top: 0; left: 100%; margin-left: 50px; height: auto; visibility: hidden; width: 100%; opacity: 0; overflow: hidden; z-index: 10; background-color: #fff; padding: 0; transition: all 0.3s ease-in-out; } .vertical_menu_float .second .inner ul li ul.vertical_submenu_start{ opacity: 1; margin-left:0; visibility: visible; } .vertical_menu_enabled.vertical_menu_transparency_on:not(.vertical_menu_hidden) aside.vertical_menu_area .vertical_menu_float .second .inner ul li ul, .vertical_menu_enabled.vertical_menu_transparency_on:not(.vertical_menu_hidden) aside.vertical_menu_area .vertical_menu_float .menu-item .second { background-color: transparent !important; } .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul > li.menu-item-has-children > a > .plus, .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul > li.menu-item-has-children > a > .plus, .vertical_menu_transparency_on .light nav.vertical_menu_float ul > li.menu-item-has-children > a > .plus{ background-image: url('img/vertical_menu_cross_white.png'); } .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .vertical_menu_transparency_on .light nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus{ background-image: url('img/vertical_menu_minus_white.png'); } .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul > li.menu-item-has-children > a > .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul > li.menu-item-has-children > a > .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_float ul > li.menu-item-has-children > a > .plus{ background-image: url('img/vertical_menu_cross_black.png'); } .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus{ background-image: url('img/vertical_menu_minus_black.png'); } @media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min--moz-device-pixel-ratio:1.5), only screen and (-o-min-device-pixel-ratio:150/100), only screen and (min-device-pixel-ratio:1.5), only screen and (min-resolution:160dpi) { nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, nav.vertical_menu_float ul li.menu-item-has-children a .plus{ background-image: url('img/vertical_menu_cross@1_5x.png'); } .no-touch nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, .no-touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .no-touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { background-image: url('img/vertical_menu_minus@1_5x.png'); } .touch nav.vertical_menu_toggle ul > li.menu-item-has-children.open > a > .plus, .touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { background-image: url('img/vertical_menu_minus@1_5x.png'); } .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, .vertical_menu_transparency_on .light nav.vertical_menu_float ul li.menu-item-has-children a .plus{ background-image: url('img/vertical_menu_cross_white@1_5x.png'); } .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .vertical_menu_transparency_on .light nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { background-image: url('img/vertical_menu_minus_white@1_5x.png'); } .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_float ul li.menu-item-has-children a .plus{ background-image: url('img/vertical_menu_cross_black@1_5x.png'); } .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { background-image: url('img/vertical_menu_minus_black@1_5x.png'); } } @media only screen and (-webkit-min-device-pixel-ratio:2.0), only screen and (min--moz-device-pixel-ratio:2.0), only screen and (-o-min-device-pixel-ratio:200/100), only screen and (min-device-pixel-ratio:2.0), only screen and (min-resolution:210dpi) { nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, nav.vertical_menu_float ul li.menu-item-has-children a .plus{ background-image: url('img/vertical_menu_cross@2x.png'); } .no-touch nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, .no-touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .no-touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { background-image: url('img/vertical_menu_minus@2x.png'); } .touch nav.vertical_menu_toggle ul > li.menu-item-has-children.open > a > .plus, .touch nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .touch nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { background-image: url('img/vertical_menu_minus@2x.png'); } .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, .vertical_menu_transparency_on .light nav.vertical_menu_float ul li.menu-item-has-children a .plus{ background-image: url('img/vertical_menu_cross_white@2x.png'); } .vertical_menu_transparency_on .light nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, .vertical_menu_transparency_on .light nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .vertical_menu_transparency_on .light nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { background-image: url('img/vertical_menu_minus_white@2x.png'); } .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul li.menu-item-has-children a .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul li.menu-item-has-children a .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_float ul li.menu-item-has-children a .plus{ background-image: url('img/vertical_menu_cross_black@2x.png'); } .vertical_menu_transparency_on .dark nav.vertical_menu_toggle ul > li.menu-item-has-children > a:hover > .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_on_click ul > li.menu-item-has-children.open > a > .plus, .vertical_menu_transparency_on .dark nav.vertical_menu_float ul > li.menu-item-has-children.open > a > .plus { background-image: url('img/vertical_menu_minus_black@2x.png'); } } nav.vertical_menu_toggle ul li a .q_menu_arrow, nav.vertical_menu_on_click ul li a .q_menu_arrow, nav.vertical_menu_float ul li a .q_menu_arrow{ display: none; } nav.vertical_menu_toggle li.narrow .second .inner ul, nav.vertical_menu_on_click li.narrow .second .inner ul{ background-color: transparent; padding:0; width: 100%; } nav.vertical_menu_toggle li.narrow .second .inner ul ul, nav.vertical_menu_on_click li.narrow .second .inner ul ul{ display: none; } .vertical_menu_toggle .second .inner ul li a, .vertical_menu_on_click .second .inner ul li a, .vertical_menu_float .second .inner ul li a{ display: block; height: auto; font-family: inherit; font-size: 13px; line-height: 18px; color: #818181; margin: 0; padding: 5px 0px 5px 0px; text-decoration: none; -webkit-transition: color 0.3s ease; -moz-transition: color 0.3s ease; -o-transition: color 0.3s ease; -ms-transition: color 0.3s ease; transition: color 0.3s ease; } .vertical_menu_transparency_on .light .vertical_menu_toggle .second .inner ul li a, .vertical_menu_transparency_on .light .vertical_menu_on_click .second .inner ul li a, .vertical_menu_transparency_on .light .vertical_menu_float .second .inner ul li a{ color: #ffffff; } .vertical_menu_transparency_on .dark .vertical_menu_toggle .second .inner ul li a, .vertical_menu_transparency_on .dark .vertical_menu_on_click .second .inner ul li a, .vertical_menu_transparency_on .dark .vertical_menu_float .second .inner ul li a{ color: #000000; } .vertical_menu_toggle .second .inner ul ul li a, .vertical_menu_on_click .second .inner ul ul li a, .vertical_menu_float .second .inner ul li a{ padding-left: 15px; padding-right: 15px; } .vertical_menu_area_widget_holder{ margin:60px 0 0 0; } .vertical_menu_enabled .carousel-inner:not(.relative_position){ left: 260px !important; } .vertical_menu_area .q_social_icon_holder{ margin: 0 8px 2px 0 !important; } .vertical_menu_enabled .content{ margin-top:0 !important; padding-top:0 !important; } .boxed.vertical_menu_enabled .carousel-inner{ width: 1150px !important; left: auto !important; } .vertical_menu_enabled.vertical_menu_transparency .full_section_inner{ overflow: hidden; } .vertical_menu_enabled.vertical_menu_transparency_on:not(.vertical_menu_hidden) aside.vertical_menu_area{ background-color: transparent !important; } .vertical_menu_enabled.vertical_menu_transparency_on:not(.vertical_menu_hidden) aside.vertical_menu_area .vertical_area_background{ -webkit-transition: opacity 0.3s ease; -moz-transition: opacity 0.3s ease; -o-transition: opacity 0.3s ease; -ms-transition: opacity 0.3s ease; transition: opacity 0.3s ease; opacity: 0 !important; } .vertical_menu_enabled.vertical_menu_transparency .q_slider{ padding-left: 0px; } .vertical_menu_enabled.vertical_menu_enabled.vertical_menu_transparency .carousel-inner:not(.relative_position){ left: 0px !important; } .boxed.vertical_menu_enabled.vertical_menu_enabled.vertical_menu_transparency .carousel-inner:not(.relative_position){ left: auto !important; } .vertical_menu_enabled.vertical_menu_transparency .carousel-control.left{ bottom: 60px; height: 44px; right: 105px; top: auto; width: 44px; } .vertical_menu_enabled.vertical_menu_transparency .carousel-control.right{ bottom: 60px; height: 44px; right: 50px; top: auto; width: 44px; } .vertical_menu_enabled.vertical_menu_transparency .carousel-control .prev_nav { left: 0; margin: 0 !important; top: 0; height: 40px; width: 40px; line-height: 40px; } .vertical_menu_enabled.vertical_menu_transparency .carousel-control .next_nav { margin: 0 !important; right: 0; top: 0; height: 40px; width: 40px; line-height: 40px; } .vertical_menu_enabled.vertical_menu_transparency .carousel-control i { font-size: 24px; line-height: 40px; } .vertical_menu_enabled.vertical_menu_transparency .carousel-indicators{ display: none !important; } .vertical_menu_enabled.page-template-landing_page-php .q_slider, .vertical_menu_enabled.page-template-landing_page-php .full_width, .vertical_menu_enabled.page-template-landing_page-php .content .container, .vertical_menu_enabled.page-template-landing_page-php .title_outer, .boxed.vertical_menu_enabled.page-template-landing_page-php, .vertical_menu_enabled.page-template-landing_page-php .full_screen_holder{ padding-left: 0px !important; } .vertical_menu_enabled.page-template-landing_page-php .carousel-inner:not(.relative_position){ left: 0px !important; } /* vertical menu - hidden type START */ .vertical_menu_hidden aside.vertical_menu_area{ -webkit-box-shadow: 0px 0px 2px 2px rgba(0,0,0,.15); box-shadow: 0px 0px 2px 2px rgba(0,0,0,.15); left: -220px; padding: 10px 40px; -webkit-transition: left 0.15s ease-out; -moz-transition: left 0.15s ease-out; -o-transition: left 0.15s ease-out; -ms-transform: left 0.15s ease-out; transition: left 0.15s ease-out; } .vertical_menu_hidden .vertical_area_background{ left: -220px; -webkit-transition: left 0.15s ease-out; -moz-transition: left 0.15s ease-out; -o-transition: left 0.15s ease-out; -ms-transform: left 0.15s ease-out; transition: left 0.15s ease-out; } .vertical_menu_hidden.vertical_menu_hidden_with_logo aside.vertical_menu_area, .vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_area_background { left: -190px; } .vertical_menu_hidden aside.vertical_menu_area.active, .vertical_menu_hidden aside.vertical_menu_area.active .vertical_area_background{ left: 0px; } .vertical_menu_enabled.vertical_menu_hidden .full_screen_holder, .vertical_menu_enabled.vertical_menu_hidden .q_slider, .vertical_menu_enabled.vertical_menu_hidden .full_width, body.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_hidden .content .full_width, .vertical_menu_enabled.vertical_menu_hidden .content .container, .vertical_menu_enabled.vertical_menu_hidden .title_outer, .vertical_menu_enabled.vertical_menu_hidden footer, .boxed.vertical_menu_enabled.vertical_menu_hidden, .boxed.vertical_menu_enabled.vertical_menu_hidden footer.uncover, .vertical_menu_enabled.vertical_menu_hidden .full_screen_holder{ padding-left: 40px; } .vertical_menu_enabled.vertical_menu_hidden .carousel-inner:not(.relative_position){ left: 40px !important; } .vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .full_screen_holder, .vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .q_slider, .vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .full_width, .vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .content .container, .vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .title_outer, .vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo footer, .boxed.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo, .boxed.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo footer.uncover, .vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .full_screen_holder{ padding-left: 70px; } .vertical_menu_enabled.vertical_menu_hidden .carousel-control .prev_nav, .vertical_menu_enabled.vertical_menu_hidden .carousel-control .next_nav{ margin-top: -27px !important; } .vertical_menu_hidden_button{ position: fixed; top: 0; left: 0px; width: 40px; height: 40px; z-index: 11; display: block; } .vertical_menu_enabled.vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_menu_hidden_button { width: 70px; height: 40px; z-index: 1000; } .vertical_menu_hidden_button_line { position: absolute; top: 50%; left: 50%; font-size: 30px; display: block; margin-left: -11px; width: 22px; height: 3px; background: #303030; } .vertical_menu_hidden_button_line:after,.vertical_menu_hidden_button_line:before{ content: ''; position: absolute; width: 100%; height: 3px; background: #303030; left: 0; -webkit-transform-origin:center center; -moz-transform-origin:center center; -ms-transform-origin:center center; -o-transform-origin:center center; transform-origin:center center; } .vertical_menu_hidden_button_line:before{ top: -6px; } .vertical_menu_hidden_button_line:after{ bottom: -6px; } .vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line{ background: rgba(220, 151, 31,0); } .vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line:after{ -webkit-transform: rotate(-45deg) translate(2px,-8px); -moz-transform: rotate(-45deg) translate(3px,-8px); -ms-transform: rotate(-45deg) translate(3px,-8px); -o-transform: rotate(-45deg) translate(3px,-8px); transform: rotate(-45deg) translate(3px,-8px); } .vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line:before{ -webkit-transform: rotate(45deg) translate(4px,9px); -moz-transform: rotate(45deg) translate(3px,8px); -ms-transform: rotate(45deg) translate(3px,8px); -o-transform: rotate(45deg) translate(3px,8px); transform: rotate(45deg) translate(3px,8px); } .vertical_menu_hidden_button_line, .vertical_menu_hidden_button_line:before, .vertical_menu_hidden_button_line:after{ -webkit-transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); -moz-transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); -ms-transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); -o-transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); transition: all 0.3s cubic-bezier(0.585, -0.600, 0.430, 1.650); } .vertical_menu_hidden_button:hover .vertical_menu_hidden_button_line:before{ top: -8px; } .vertical_menu_hidden_button:hover .vertical_menu_hidden_button_line:after{ bottom: -8px; } .vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line:after{ bottom: -8px; } .vertical_menu_area.active .vertical_menu_hidden_button .vertical_menu_hidden_button_line:before{ top: -8px; } .vertical_menu_hidden .vertical_menu_area_bottom_logo { position: fixed; width: 70px; text-align: center; bottom: 0px; z-index: 1000; } .vertical_menu_hidden .vertical_menu_area_bottom_logo_inner { position: absolute; bottom: 20px; box-sizing: border-box; text-align: center; width: 100%; } .vertical_menu_hidden .vertical_menu_area_bottom_logo_inner a { display: block; padding: 0 10px; } .vertical_menu_hidden .vertical_menu_area_bottom_logo{ left: 0; -webkit-transition: left 0.15s ease-in-out; -moz-transition: left 0.15s ease-in-out; -ms-transition: left 0.15s ease-in-out; -o-transition: left 0.15s ease-in-out; transition: left 0.15s ease-in-out; } .vertical_menu_hidden .vertical_menu_area_bottom_logo.active{ left: -70px; } .vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_menu_area:not(.active) .vertical_menu_area_inner{ left: -30px; } .vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_menu_area .vertical_menu_area_inner { left: 0; } .vertical_menu_hidden.vertical_menu_hidden_with_logo .vertical_menu_area .vertical_menu_area_inner { position: relative; height: 100%; } /*vertical menu width for initially hidden type*/ .vertical_menu_hidden.vertical_menu_width_290 aside.vertical_menu_area, .vertical_menu_hidden.vertical_menu_width_290 aside.vertical_menu_area .vertical_area_background{ width:290px; left:-250px; } .vertical_menu_hidden.vertical_menu_width_350 aside.vertical_menu_area, .vertical_menu_hidden.vertical_menu_width_350 aside.vertical_menu_area .vertical_area_background{ width:350px; left:-310px; } .vertical_menu_hidden.vertical_menu_width_400 aside.vertical_menu_area, .vertical_menu_hidden.vertical_menu_width_400 aside.vertical_menu_area .vertical_area_background{ width:400px; left:-360px; } .vertical_menu_hidden.vertical_menu_width_290 aside.vertical_menu_area.active, .vertical_menu_hidden.vertical_menu_width_290 aside.vertical_menu_area.active .vertical_area_background, .vertical_menu_hidden.vertical_menu_width_350 aside.vertical_menu_area.active, .vertical_menu_hidden.vertical_menu_width_350 aside.vertical_menu_area.active .vertical_area_background, .vertical_menu_hidden.vertical_menu_width_400 aside.vertical_menu_area.active, .vertical_menu_hidden.vertical_menu_width_400 aside.vertical_menu_area.active .vertical_area_background{ left:0; } /*vertical menu width for initially hidden type with logo at bottom */ .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_290 aside.vertical_menu_area, .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_290 aside.vertical_menu_area .vertical_area_background{ width:290px; left:-220px; } .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_350 aside.vertical_menu_area, .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_350 aside.vertical_menu_area .vertical_area_background{ width:350px; left:-280px; } .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_400 aside.vertical_menu_area, .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_400 aside.vertical_menu_area .vertical_area_background{ width:400px; left:-330px; } .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_290 aside.vertical_menu_area.active, .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_290 aside.vertical_menu_area.active .vertical_area_background, .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_350 aside.vertical_menu_area.active, .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_350 aside.vertical_menu_area.active .vertical_area_background, .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_400 aside.vertical_menu_area.active, .vertical_menu_hidden.vertical_menu_hidden_with_logo.vertical_menu_width_400 aside.vertical_menu_area.active .vertical_area_background{ left:0; } /* vertical menu - hidden type END */ /* ========================================================================== End Vertical menu styles ========================================================================== */ /* ========================================================================== Popup menu start styles ========================================================================== */ .popup_menu_inner{ display: inline-block; height: 2px; position: relative; top: -1px; vertical-align: middle; width: 20px; position: relative; width: 20px; } .popup_menu .line{ background-color: #9D9D9D; height: 2px; margin: 0px; width: 13px; top: 0px; left: 0px; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; -ms-transform: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; position: absolute; display: inline-block; } .popup_menu .line:after, .popup_menu .line:before { background-color: #9D9D9D; content: ""; display: block; height: 2px; position: absolute; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; -ms-transform: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; width: 13px; z-index: -1; -webkit-backface-visibility: hidden; /*because X sign jumps on hover in Chrome*/ } @media only screen and (min-width: 1000px) { .dark:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line, .dark:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line:before, .dark:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line:after, .dark.header_style_on_scroll .popup_menu:not(.opened) .line, .dark.header_style_on_scroll .popup_menu:not(.opened) .line:before, .dark.header_style_on_scroll .popup_menu:not(.opened) .line:after{ background-color: #000; } .light:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line, .light:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line:before, .light:not(.sticky):not(.scrolled) .popup_menu:not(.opened) .line:after, .light.header_style_on_scroll .popup_menu:not(.opened) .line, .light.header_style_on_scroll .popup_menu:not(.opened) .line:before, .light.header_style_on_scroll .popup_menu:not(.opened) .line:after{ background-color: #fff; } } .popup_menu .line:before { top: -4px; } .popup_menu .line:after { top: 4px; } .side_menu_button .popup_menu:hover{ opacity: 0.8; } .popup_menu.opened .line{ background-color: transparent !important; } .popup_menu.opened .line:after { background-color: #ffffff; top: 0 !important; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -o-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg); } .popup_menu.opened .line:before { background-color: #ffffff; top: 0 !important; -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -o-transform: rotate(-45deg); -ms-transform: rotate(-45deg); transform: rotate(-45deg); } .popup_menu_holder_outer{ position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; visibility: hidden; opacity: 0; z-index: 105; /* this have to be between header z-index and content z-index */ } .popup_menu_holder{ width: 100%; height: 100%; background-color: rgba(48,48,48,0.95); -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; display: table; } .popup_menu_holder_inner{ display: table-cell; vertical-align: middle; padding: 100px 0px; } .popup_menu_opened .main_menu, .popup_menu_opened .side_menu_button a:not(.popup_menu), .popup_menu_opened #back_to_top, .popup_menu_opened .header_top, .popup_menu_opened header .tooltip, .popup_menu_opened .mobile_menu_button, .popup_menu_opened .fixed_top_header .header_bottom_center_widget, .popup_menu_opened .fixed_top_header .header_bottom_right_widget_holder{ visibility: hidden !important; } .popup_menu_opened .header_bottom .container_inner{ border: none !important; } .popup_menu_opened .side_menu_button .shopping_cart_header{ display: none; } .popup_menu_opened .popup_menu_holder_outer{ visibility: visible; opacity: 1; } .touch .popup_menu_holder_outer{ display: none; } .touch .popup_menu_opened .popup_menu_holder_outer{ display: block; } .popup_menu_opened header.scrolled .header_bottom, .popup_menu_opened header.sticky .header_bottom{ background-color: transparent !important; box-shadow: none; } .popup_menu_opened .header_top, .popup_menu_opened .header_bottom, .popup_menu_opened .fixed_top_header .top_header{ background-color: transparent !important; border: 0px !important; } .popup_menu_opened .q_logo img.normal, .popup_menu_opened .q_logo img.light, .popup_menu_opened .q_logo img.sticky, .popup_menu_opened .q_logo img.dark, .popup_menu_opened .q_logo img.mobile { opacity: 0 !important; } .popup_menu_opened header .q_logo img.popup{ opacity: 1 !important; } nav.popup_menu{ margin: 0px auto; position: relative; top: 0px; text-align: left; } nav.popup_menu ul{ display: none; position: relative; list-style: none; padding: 0; margin: 0; } nav.popup_menu > ul{ display: block; } nav.popup_menu ul li{ margin: 0; padding: 0; text-align: center; font-size: 45px; line-height: 50px; } nav.popup_menu ul li a, nav.popup_menu ul li h6{ font-size: 24px; font-weight: 500; line-height: 50px; letter-spacing: 2px; color: #ffffff; padding: 0px; display: block; position: relative; text-decoration: none; text-transform: uppercase; cursor: pointer; } nav.popup_menu ul li a:hover, nav.popup_menu ul li h6:hover{ color: #9c9c9c; } nav.popup_menu ul li a span, nav.popup_menu ul li h6 span{ display: inline-block; vertical-align: middle; } nav.popup_menu ul li ul li a, nav.popup_menu ul li ul li h6{ font-size: 14px; text-transform: none; } nav.popup_menu ul li ul li ul li a, nav.popup_menu ul li ul li ul li h6{ font-size: 0.5em; line-height: 1em; } .popup_menu.medium .popup_menu_inner, .popup_menu.medium .line, .popup_menu.medium .line:after, .popup_menu.medium .line:before { height: 3px; width: 19px; } .popup_menu.medium .line:before{ top: -6px; } .popup_menu.medium .line:after { top: 6px; } .popup_menu.large .popup_menu_inner, .popup_menu.large .line, .popup_menu.large .line:after, .popup_menu.large .line:before { height: 4px; width: 24px; } .popup_menu.large .line:before{ top: -8px; } .popup_menu.large .line:after { top: 8px; } /* ========================================================================== Popup menu end styles ========================================================================== */ /* ========================================================================== Pricing List Shortcode style ========================================================================== */ .qode_pricing_list .qode_pricing_list_holder { list-style: none; } .qode_pricing_list .qode_pricing_list_item { position: relative; border-bottom: 1px solid #e7e7e7; padding: 19px 0; } .qode_pricing_list .qode_pricing_item_title { margin-bottom: 5px; font-size: 18px; font-weight: 600; } .qode_pricing_list .qode_pricing_item_text { padding-right: 170px; } .qode_pricing_list .qode_pricing_item_price { position: absolute; width: 170px; height: 100%; text-align: right; right: 0; top: 0; } .qode_pricing_list .qode_pricing_item_price_inner { display: table; height: 100%; width: 100%; } .qode_pricing_list .qode_pricing_item_price_inner span { display: table-cell; vertical-align: middle; font-size: 30px; color: #303030; font-weight: 600; } /* ========================================================================== End of Pricing List Shortcode style ========================================================================== */ /* ========================================================================== Qode Elements Holder style ========================================================================== */ .q_elements_holder{ width: 100%; display: table; table-layout: fixed; } .q_elements_holder .q_elements_item{ display: table-cell; vertical-align: middle; height: 100%; } .q_elements_holder .q_elements_item_inner{ width: 100%; } .q_elements_holder.two_columns .q_elements_item { width: 50%; } .q_elements_holder.three_columns .q_elements_item { width: 33.33333333333333%; } .q_elements_holder.four_columns .q_elements_item { width: 25%; } /* ========================================================================== End of Qode Elements Holder style ========================================================================== */ /* ========================================================================== Start of content with negative margin style ========================================================================== */ .content_top_margin .content .container .container_inner.page_container_inner{ padding: 0px; } .content_top_margin .content .container .container_inner .call_to_action{ margin: 0px -15px; } .content_top_margin .content .container .container_inner .call_to_action .container_inner{ width: 100%; } /* ========================================================================== End of content with negative margin style ========================================================================== */ /* ========================================================================== Password protected box styles ========================================================================== */ .post-password-form { width: 300px; } .post-password-form p { margin-bottom: 20px; } .post-password-form input[type='password'] { width: 100%; display: block; margin: 5px 0 20px; padding: 15px 12px; border: 0; outline: 0; resize: none; font-size: 13px; line-height:17px; background-color:#fff; color: #818181; font-family: inherit; font-weight:400; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .post-password-form input[type='submit'] { position: relative; display: inline-block; width: auto; height: 39px; line-height: 39px; margin: 0; padding: 0px 23px; border: 2px solid #303030; font-size: 13px; font-weight: 700; font-family: inherit; text-align: left; color: #303030; text-decoration: none; cursor: pointer; white-space: nowrap; outline: none; font-style: normal; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 20px; -o-border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; text-shadow: none; background-color: transparent; -webkit-transition: all 0.1s linear; -moz-transition: all 0.1s linear; -ms-transition: all 0.1s linear; -o-transition: all 0.1s linear; transition: all 0.1s linear; -webkit-box-sizing: initial !important; -moz-box-sizing: initial !important; box-sizing: initial !important; } .post-password-form input[type='submit']:hover { background-color: #1abc9c; border-color: #1abc9c; color: #fff; text-decoration: none; } /* ========================================================================== End of password protected box styles ========================================================================== */ /* ========================================================================== Full Screen Sections Template ========================================================================== */ .full_screen_holder{ position: relative; display: block; z-index: 100; } .full_screen_inner{ height: 100%; position: relative; /* Touch detection for Windows 8 */ -ms-touch-action: none; /* IE 11 on Windows Phone 8.1*/ touch-action: none; visibility: hidden; } .fp-section { position: relative; -webkit-box-sizing: border-box; /* Safari<=5 Android<=3 */ -moz-box-sizing: border-box; /* <=28 */ box-sizing: border-box; margin: 0 !important; } .fp-slide { float: left; } .fp-section.fp-table, .fp-slide.fp-table { display: table; width: 100%; } .fp-tableCell { display: table-cell; vertical-align: middle; width: 100%; height: 100%; } .vertical_menu_enabled .full_screen_holder{ padding-left: 260px; } .boxed.vertical_menu_enabled .full_screen_holder{ padding-left: 0; } @media only screen and (max-width: 1000px){ .vertical_menu_enabled .full_screen_holder{ padding-left: 0; } } .full_screen_navigation_holder{ position: absolute; left: 0; width: 100%; display: block; text-align: center; z-index: 10000; visibility: hidden; -webkit-transition: opacity 0.3s ease-in-out; -moz-transition: opacity 0.3s ease-in-out; -ms-transition: opacity 0.3s ease-in-out; -o-transition: opacity 0.3s ease-in-out; transition: opacity 0.3s ease-in-out; } .full_screen_navigation_holder.up_arrow{ top: 30px; } .full_screen_navigation_holder.down_arrow, .full_screen_navigation_holder.side_by_side{ position: fixed; bottom: 30px; } .full_screen_navigation_inner{ position: relative; display: inline-block; vertical-align: middle; } .full_screen_navigation_inner a{ display: block; color: #393939; font-size: 40px; line-height: 1em; opacity: 1; -webkit-transition: opacity 0.3s ease-in-out; -moz-transition: opacity 0.3s ease-in-out; -ms-transition: opacity 0.3s ease-in-out; -o-transition: opacity 0.3s ease-in-out; transition: opacity 0.3s ease-in-out; } .full_screen_navigation_inner a:hover{ opacity: 0.7; } .full_screen_navigation_inner i{ font-size: inherit; color: inherit; line-height: inherit; } .full_screen_preloader{ position: absolute; height: 1200px; width: 100%; display: block; background-color: #1c1c1c; z-index: 10001; } .full_screen_preloader .ajax_loader{ position: absolute; display: block; } /* ========================================================================== End of Full Screen Sections Template ========================================================================== */ /* ========================================================================== Image Gallery slider with no space ========================================================================== */ .qode_image_gallery_no_space { opacity: 0; position: relative; } .qode_image_gallery_no_space .qode_image_gallery_holder { overflow: hidden; position: relative; width: 100%; } .qode_image_gallery_no_space ul { margin: 0; overflow: hidden; padding: 0; } .qode_image_gallery_no_space ul li { float: left; list-style: none outside none; margin: 0px; } @media only screen and (min-width: 800px) { .qode_image_gallery_no_space.highlight_active ul li:not(.active) { opacity: 0.2; } .qode_image_gallery_no_space.highlight_active ul li.active{ opacity: 1 !important; } .qode_image_gallery_no_space.highlight_active ul li { -webkit-transition: opacity 0.3s ease-in-out; -moz-transition: opacity 0.3s ease-in-out; -ms-transition: opacity 0.3s ease-in-out; -o-transition: opacity 0.3s ease-in-out; transition: opacity 0.3s ease-in-out; } } @media only screen and (max-width: 800px) { .qode_image_gallery_no_space.highlight_active ul li{ opacity: 1 !important; } } .qode_image_gallery_no_space ul li:not(.active) a { cursor: default; } .qode_image_gallery_no_space a.prettyphoto { display: block; width: 100%; height: 100%; } .qode_image_gallery_no_space ul li img { display: block; position: relative; } .qode_image_gallery_no_space .controls { width: 100%; } .qode_image_gallery_no_space .controls a.prev-slide, .qode_image_gallery_no_space .controls a.next-slide { vertical-align: middle; font-size: 30px; position: absolute; top: 0; height: 100%; width: 10%; } .qode_image_gallery_no_space .controls a.prev-slide span, .qode_image_gallery_no_space .controls a.next-slide span { margin-top: -27px; margin-left: -27px; position: absolute; left: 50%; top: 50%; background-color: transparent; border: 2px solid #303030; color: #303030; cursor: pointer; display: block; height: 54px; line-height: 54px; text-align: center; width: 54px; border-radius: 40px; -webkit-transition: color .15s ease-in-out, background-color .15s ease-in-out; -moz-transition: color .15s ease-in-out, background-color .15s ease-in-out; -ms-transition: color .15s ease-in-out, background-color .15s ease-in-out; -o-transition: color .15s ease-in-out, background-color .15s ease-in-out; transition: color .15s ease-in-out, background-color .15s ease-in-out; } .qode_image_gallery_no_space .controls a.prev-slide span i, .qode_image_gallery_no_space .controls a.next-slide span i{ vertical-align: top; } .qode_image_gallery_no_space.light .controls a.prev-slide span, .qode_image_gallery_no_space.light .controls a.next-slide span{ color: #fff; border-color: #fff; } .qode_image_gallery_no_space.dark .controls a.prev-slide span, .qode_image_gallery_no_space.dark .controls a.next-slide span{ color: #000; border-color: #000; } .qode_image_gallery_no_space .controls a.prev-slide:hover span, .qode_image_gallery_no_space .controls a.next-slide:hover span{ background-color: #303030; color: #fff; } .qode_image_gallery_no_space.light .controls a.prev-slide:hover span, .qode_image_gallery_no_space.light .controls a.next-slide:hover span{ background-color: #fff; color: #8a8a8a; } .qode_image_gallery_no_space.dark .controls a.prev-slide:hover span, .qode_image_gallery_no_space.dark .controls a.next-slide:hover span{ background-color: #000; color: #fff; } .qode_image_gallery_no_space .controls a.next-slide { right: 20px; } @media only screen and (max-width: 800px) { .qode_image_gallery_no_space .qode_image_gallery_holder { height: auto !important; } .qode_image_gallery_no_space ul { height: auto !important; width: 100% !important; } .qode_image_gallery_no_space ul li { float: none; } .qode_image_gallery_no_space ul li.-before, .qode_image_gallery_no_space ul li.-after { display: none; } .qode_image_gallery_no_space ul li div { height: auto !important; width: 100% !important; } .qode_image_gallery_no_space ul li img { height: auto; width: 100%; } .qode_image_gallery_no_space .controls { display: none; } } /* ========================================================================== End of Image Gallery slider with no space ========================================================================== */ /* ========================================================================== Start of Countdown ========================================================================== */ /* jQuery Countdown styles 2.0.0. */ .countdown-rtl { direction: rtl; } .countdown-row { clear: both; width: 100%; padding: 0px 2px; text-align: center; } .countdown-show1 .countdown-section { width: 98%; } .countdown-show2 .countdown-section { width: 48%; } .countdown-show3 .countdown-section { width: 32.5%; } .countdown-show4 .countdown-section { width: 24.5%; } .countdown-show5 .countdown-section { width: 19.5%; } .countdown-show6 .countdown-section { width: 16.25%; } .countdown-show7 .countdown-section { width: 14%; } .countdown{ font-weight: 700; } .countdown-section { display: inline-block; vertical-align: middle; text-align: center; font-weight: inherit; } .countdown-amount { display: block; position: relative; font-size: 60px; line-height: 60px; margin-bottom: 20px; color: inherit; } /*this span.countdown_separator is added in countdown plugin in plugin.js file */ .countdown_separator{ display: none; width: 30px; height: 2px; background-color: #818181; margin: 30px 0px; opacity: 0.3; } .countdown.show_separator .countdown_separator{ display: inline-block; } .countdown.show_separator .countdown-amount { margin: 0px; } .countdown-period { display: block; font-size: 15px; letter-spacing: 1px; text-transform: uppercase; color: inherit; } .countdown-descr { display: block; width: 100%; } @media only screen and (max-width: 1000px){ .countdown-amount { font-size: 50px !important; line-height: 50px !important; } .countdown-period { font-size: 15px !important; } .countdown_separator { width: 30px; } } @media only screen and (max-width: 600px){ .countdown-amount { font-size: 40px !important; line-height: 40px !important; margin-bottom: 15px; } .countdown-period { font-size: 12px !important; } .countdown_separator { width: 20px; margin: 25px 0px 20px 0px; } } @media only screen and (max-width: 600px){ .countdown-amount { font-size: 35px !important; line-height: 35px !important; margin-bottom: 10px; } .countdown-period { font-size: 10px !important; } .countdown_separator { width: 15px; margin: 20px 0px 15px 0pc; } } /* ========================================================================== End of Countdown ========================================================================== */ /* ========================================================================== Start of Vertical Split Screen ========================================================================== */ .vertical_split_slider{ opacity: 0; position: relative; margin: 0px -2px; } .ms-section { position: relative; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; background-size: cover; background-repeat: no-repeat; padding: 0px 20px; } .vertical_split_slider .ms-left .ms-section{ background-position: 100% center !important; } .vertical_split_slider .ms-right .ms-section{ background-position: 0 center !important; } .ms-section.ms-table{ display: table; width: 100%; } .ms-tableCell { display: table-cell; vertical-align: middle; width: 100%; height: 100%; box-sizing: border-box; } .ms-easing { -webkit-transition: all 0.7s ease-out; -moz-transition: all 0.7s ease-out; -o-transition: all 0.7s ease-out; transition: all 0.7s ease-out; } #multiscroll-nav { position: fixed; z-index: 1000; margin-top: -32px; top: 50%; opacity: 1; } #multiscroll-nav.right { right: 17px; } #multiscroll-nav.left { left: 17px; } #multiscroll-nav ul{ margin: 0; padding: 0; } #multiscroll-nav li{ display: block; width: 8px; height: 8px; margin: 13px 7px; position: relative; } #multiscroll-nav li a{ display: block; position: relative; z-index: 1; width: 100%; height: 100%; cursor: pointer; text-decoration: none; } #multiscroll-nav li .active span{ background-color: #000; } #multiscroll-nav span{ top: 0px; left: 0px; width: 8px; height: 8px; border: 1px solid #000; background-color: rgba(0, 0, 0, 0); -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; position: absolute; z-index: 1; } .multiscroll-tooltip { position: absolute; color: #fff; font-size: 14px; font-family: arial, helvetica, sans-serif; top: -2px; white-space: nowrap; max-width: 220px; } .multiscroll-tooltip.right { right: 20px; } .multiscroll-tooltip.left { left: 20px; } .vertical_split_slider_responsive{ display: none; } @media only screen and (max-width: 1000px){ .vertical_split_slider .ms-left { width: 100% !important; z-index: 2; } .vertical_split_slider .ms-left .ms-section{ background: none !important; text-align: center !important; } .vertical_split_slider .ms-right { width: 100% !important; z-index: 1; } } @media only screen and (max-width: 767px){ .vertical_split_screen_initalized body.vss_responsive_adv{ overflow-y: visible !important; height: auto !important; } .vss_responsive_adv .vertical_split_slider, .vss_responsive_adv #multiscroll-nav { display: none; } .vertical_split_slider_responsive{ display: block; } .vss_responsive_adv .ms-section { background-position: center center; } } /* ========================================================================== End of Vertical Split Screen ========================================================================== */ /* ========================================================================== Start of paspartu ========================================================================== */ .paspartu_outer{ padding: 0 2% 0% 2%; z-index: 99; /* 100 is z-index of footer, so it needs to be smaller in order to prevent minus margin on left and right paspartu */ } .paspartu_outer:not(.paspartu_on_bottom_fixed){ position: relative; } body:not(.paspartu_on_top_fixed) .paspartu_outer .content:not(.has_slider) .content_inner, .paspartu_on_top_fixed header, .paspartu_on_top_fixed .fixed_top_header .top_header, .paspartu_on_top_fixed .paspartu_outer .content_wrapper{ padding-top: 2%; } .paspartu_left, .paspartu_right { position: absolute; height: 100%; width: 2%; top: 0px; left: 0px; background-color: #ffffff; z-index: 101; /* one more than the Slider */ } .paspartu_outer:not(.paspartu_on_bottom_fixed):not(.disable_top_paspartu):not(disable_bottom_paspartu) .paspartu_left, .paspartu_outer:not(.paspartu_on_bottom_fixed):not(.disable_top_paspartu):not(disable_bottom_paspartu) .paspartu_right{ /*margin: -50% 0px; *//* because of the header types when portfolio outer is not from top of window */ height: 200%; margin: -5% 0; } .paspartu_right{ left: auto; right: 0px; } .paspartu_top{ position: fixed; padding-top: 2%; height: 0; width: 100%; top:0px; left: 0px; background-color: #ffffff; z-index: 200; } .paspartu_bottom{ position: relative; padding-top: 2%; height: 0; width: 100%; background-color: #ffffff; z-index: 200; } .paspartu_on_bottom_fixed .paspartu_bottom{ position: fixed; bottom:0px; left: 0px; } .paspartu_on_bottom_fixed footer{ margin-bottom: 2%; } body.paspartu_on_top_fixed.paspartu_on_bottom_fixed .popup_menu_holder_outer{ padding: 2%; box-sizing: border-box; } .paspartu_enabled #multiscroll-nav.right{ padding-right: 2%; } .paspartu_outer .q_slider, .paspartu_outer .content:not(.has_slider) .content_inner{ background-color: #ffffff; } .paspartu_outer:not(.disable_top_paspartu) .carousel-inner, .paspartu_outer.paspartu_on_bottom_slider .carousel-inner{ position: relative; height: 100% !important; } .paspartu_outer.disable_top_paspartu .content:not(.has_slider) .content_inner{ padding-top: 0 !important; } .paspartu_outer.disable_bottom_paspartu, .paspartu_outer.paspartu_on_bottom_fixed{ padding-bottom: 0 !important; } .paspartu_enabled .header_inner{ position: relative; /* for search form that covers header and comes from bottom from header */ } header.paspartu_header_alignment .header_bottom{ padding: 0px 2%; } header.paspartu_header_inside, .paspartu_enabled.vertical_menu_enabled header{ padding-left: 2%; padding-right: 2%; box-sizing: border-box; } .paspartu_enabled.paspartu_on_top_fixed .fixed_top_header .qode_search_form_3{ margin-top: 2%; } header.paspartu_header_inside.fixed_top_header .top_header, .paspartu_enabled .vertical_split_slider_preloader, .paspartu_enabled.paspartu_on_top_fixed .fixed_top_header .qode_search_form_3{ width: 96%; margin-left: 2%; margin-right: 2%; } .paspartu_enabled .paspartu_outer:not(.disable_top_paspartu) .vertical_split_slider{ margin-top: -2%; } .paspartu_enabled .paspartu_outer:not(.disable_bottom_paspartu) .vertical_split_slider{ margin-bottom: -2%; } .paspartu_on_top_fixed header{ z-index:202; } .paspartu_on_top_fixed:not(.paspartu_on_bottom_fixed) .popup_menu_holder_outer{ z-index:201; } .paspartu_enabled.vertical_menu_inside_paspartu aside.vertical_menu_area, .paspartu_enabled.vertical_menu_inside_paspartu .vertical_area_background, .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_enabled .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_inside_paspartu .vertical_menu_hidden_button{ margin-left: 2%; } .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right aside.vertical_menu_area, .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right .vertical_area_background, .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_enabled.vertical_menu_right .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right .vertical_menu_hidden_button{ margin-left: 0%; margin-right: 2%; } .paspartu_enabled.vertical_menu_inside_paspartu aside.vertical_menu_area, .paspartu_enabled.vertical_menu_inside_paspartu .vertical_area_background, .paspartu_enabled.vertical_menu_inside_paspartu .vertical_menu_hidden_button{ margin-top: 2%; } .paspartu_enabled.vertical_menu_enabled:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer:not(.disable_top_paspartu) .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_enabled:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer.paspartu_on_bottom_slider .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_enabled.vertical_menu_width_290:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer:not(.disable_top_paspartu) .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_enabled.vertical_menu_width_290:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer.paspartu_on_bottom_slider .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_enabled.vertical_menu_width_350:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer:not(.disable_top_paspartu) .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_enabled.vertical_menu_width_350:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer.paspartu_on_bottom_slider .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_enabled.vertical_menu_width_400:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer:not(.disable_top_paspartu) .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_enabled.vertical_menu_width_400:not(.vertical_menu_hidden):not(.vertical_menu_transparency) .paspartu_outer.paspartu_on_bottom_slider .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_enabled.vertical_menu_hidden .carousel-inner:not(.relative_position){ left: 0px !important; margin-left: 0% !important; } .vertical_menu_enabled.paspartu_on_top_fixed header{ padding: 0px !important; } /* outside paspartu - start */ .paspartu_enabled.vertical_menu_outside_paspartu aside.vertical_menu_area{ z-index: 500; } body.vertical_menu_outside_paspartu.paspartu_on_top_fixed .paspartu_outer{ padding-top: 2%; } body.paspartu_on_top_fixed.vertical_menu_outside_paspartu .paspartu_outer .content .content_inner{ padding-top: 0% !important; } @media only screen and (min-width: 1000px) { .vertical_menu_outside_paspartu .content_wrapper{ margin-left: 2%; padding-left: 260px; width: 98%; } .vertical_menu_outside_paspartu.vertical_menu_left.vertical_menu_width_290 .content_wrapper{ margin-left: 2%; padding-left: 290px; width: 98%; } .vertical_menu_outside_paspartu.vertical_menu_left.vertical_menu_width_350 .content_wrapper{ margin-left: 2%; padding-left: 350px; width: 98%; } .vertical_menu_outside_paspartu.vertical_menu_left.vertical_menu_width_400 .content_wrapper{ margin-left: 2%; padding-left: 400px; width: 98%; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_290 .content_wrapper{ margin-right: 2%; padding-right: 290px; width: 98%; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_350 .content_wrapper{ margin-right: 2%; padding-right: 350px; width: 98%; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_400 .content_wrapper{ margin-right: 2%; padding-right: 400px; width: 98%; } .vertical_menu_outside_paspartu .paspartu_middle_inner{ padding-left: 260px; } .vertical_menu_outside_paspartu .paspartu_left{ left: 260px; } .vertical_menu_outside_paspartu.vertical_menu_width_290 .paspartu_middle_inner{ padding-left: 290px; } .vertical_menu_outside_paspartu.vertical_menu_width_290 .paspartu_left{ left: 290px; } .vertical_menu_outside_paspartu.vertical_menu_width_350 .paspartu_middle_inner{ padding-left: 350px; } .vertical_menu_outside_paspartu.vertical_menu_width_350 .paspartu_left{ left: 350px; } .vertical_menu_outside_paspartu.vertical_menu_width_400 .paspartu_middle_inner{ padding-left: 400px; } .vertical_menu_outside_paspartu.vertical_menu_width_400 .paspartu_left{ left: 400px; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_290 .paspartu_middle_inner{ padding-left: 0px; padding-right: 290px; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_290 .paspartu_left{ left: 0px; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_290 .paspartu_right{ right: 290px; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_350 .paspartu_middle_inner{ padding-left: 0px; padding-right: 350px; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_350 .paspartu_left{ left: 0px; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_350 .paspartu_right{ right: 350px; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_400 .paspartu_middle_inner{ padding-left: 0px; padding-right: 400px; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_400 .paspartu_left{ left: 0px; } .vertical_menu_outside_paspartu.vertical_menu_right.vertical_menu_width_400 .paspartu_right{ right: 400px; } body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled:not(.vertical_menu_hidden) .content .full_width{ padding-left: 0px; padding-right:0px; } body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_290.vertical_menu_left:not(.vertical_menu_hidden) .content .full_width{ padding-left: 0px; padding-right:0px; } body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_350.vertical_menu_left:not(.vertical_menu_hidden) .content .full_width{ padding-left: 0px; padding-right:0px; } body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_400.vertical_menu_left:not(.vertical_menu_hidden) .content .full_width{ padding-left: 0px; padding-right:0px; } body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_290.vertical_menu_right:not(.vertical_menu_hidden) .content .full_width{ padding-right:0px; padding-left:0px; } body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_350.vertical_menu_right:not(.vertical_menu_hidden) .content .full_width{ padding-right:0px; padding-left:0px; } body.vertical_menu_outside_paspartu.page-template-blog-masonry-full-width-php.vertical_menu_enabled.vertical_menu_width_400.vertical_menu_right:not(.vertical_menu_hidden) .content .full_width{ padding-right:0px; padding-left:0px; } } .vertical_menu_outside_paspartu.vertical_menu_enabled .q_slider, .vertical_menu_outside_paspartu.vertical_menu_enabled .full_width, .vertical_menu_outside_paspartu.vertical_menu_enabled .content .container, .vertical_menu_outside_paspartu.vertical_menu_enabled .title_outer, /* .vertical_menu_outside_paspartu.vertical_menu_enabled footer, no need for footer to be excluded*/ .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .q_slider, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .full_width, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .content .container, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .title_outer, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 footer, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .q_slider, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .full_width, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .content .container, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .title_outer, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 footer, .vertical_menu_outside_paspartu.vertical_menu_enabled .full_screen_holder, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350 .full_screen_holder, .vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400 .full_screen_holder{ padding-left: 0px; padding-right: 0px; } .vertical_menu_outside_paspartu.vertical_menu_enabled .q_slider{ padding-top: 0px !important; } body.vertical_menu_outside_paspartu.vertical_menu_enabled:not(.vertical_menu_hidden) .ajax_loader, body.vertical_menu_outside_paspartu.vertical_menu_enabled:not(.vertical_menu_hidden) .ajax_loader, body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_290:not(.vertical_menu_hidden) .ajax_loader, body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350:not(.vertical_menu_hidden) .ajax_loader, body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400:not(.vertical_menu_hidden) .ajax_loader, body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_290.vertical_menu_right:not(.vertical_menu_hidden) .ajax_loader, body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_350.vertical_menu_right:not(.vertical_menu_hidden) .ajax_loader, body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_width_400.vertical_menu_right:not(.vertical_menu_hidden) .ajax_loader, body.vertical_menu_outside_paspartu.vertical_menu_enabled.vertical_menu_hidden.vertical_menu_right .ajax_loader{ margin-left: 0px; } /* outside paspartu - end */ @media only screen and (min-width: 1024px) { header.paspartu_header_alignment .header_inner_left { left: 2%; } } @media only screen and (max-width: 1024px) { .paspartu_outer { padding: 0 2% 2% 2% !important; } body:not(.paspartu_on_top_fixed) .paspartu_outer .content:not(.has_slider) .content_inner, .paspartu_top, .paspartu_bottom, .paspartu_on_top_fixed header, .paspartu_on_top_fixed .fixed_top_header .top_header, .paspartu_on_top_fixed .paspartu_outer .content_wrapper{ padding-top: 2% !important; } .paspartu_left, .paspartu_right { width: 2% !important; } .paspartu_on_bottom_fixed footer{ margin-bottom: 2% !important; } body.paspartu_on_top_fixed.paspartu_on_bottom_fixed .popup_menu_holder_outer{ padding: 2% !important; } .paspartu_enabled #multiscroll-nav.right{ padding-right: 2% !important; } header.paspartu_header_alignment .header_bottom { padding: 0px 2% !important; } header.paspartu_header_inside, .paspartu_enabled.vertical_menu_enabled header{ padding-left: 2% !important; padding-right: 2% !important; } .paspartu_enabled.paspartu_on_top_fixed .fixed_top_header .qode_search_form_3{ margin-top: 2% !important; } header.paspartu_header_inside.fixed_top_header .top_header, .paspartu_enabled .vertical_split_slider_preloader, .paspartu_enabled.paspartu_on_top_fixed .fixed_top_header .qode_search_form_3{ width: 96% !important; margin-left: 2% !important; margin-right: 2% !important; } .paspartu_enabled .paspartu_outer:not(.disable_top_paspartu) .vertical_split_slider{ margin-top: -2% !important; } .paspartu_enabled .paspartu_outer:not(.disable_bottom_paspartu) .vertical_split_slider{ margin-bottom: -2% !important; } .paspartu_enabled.vertical_menu_inside_paspartu aside.vertical_menu_area, .paspartu_enabled.vertical_menu_inside_paspartu .vertical_area_background, .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_enabled .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_inside_paspartu .vertical_menu_hidden_button{ margin-left: 2% !important; } .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right aside.vertical_menu_area, .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right .vertical_area_background, .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_enabled.vertical_menu_right .carousel-inner:not(.relative_position), .paspartu_enabled.vertical_menu_inside_paspartu.vertical_menu_right .vertical_menu_hidden_button{ margin-left: 0% !important; margin-right: 2% !important; } .paspartu_enabled.vertical_menu_inside_paspartu aside.vertical_menu_area, .paspartu_enabled.vertical_menu_inside_paspartu .vertical_area_background, .paspartu_enabled.vertical_menu_inside_paspartu .vertical_menu_hidden_button{ margin-top: 2% !important; } body.vertical_menu_outside_paspartu.paspartu_on_top_fixed .paspartu_outer{ padding-top: 2% !important; } } /* ========================================================================== End of paspartu ========================================================================== */ /* ========================================================================== Visual Composer Grid Elements ============================================================================ */ .vc_grid-container .vc_row.vc_grid .vc_grid-item .vc_btn { position: relative; display: inline-block; width: auto; height: 39px; line-height: 39px; margin: 0; padding: 0px 23px; border: 2px solid #303030; font-size: 13px; font-weight: 700; font-family: inherit; text-align: left; color: #303030 !important; text-decoration: none; cursor: pointer; white-space: nowrap; outline: none; font-style: normal; text-transform: uppercase; letter-spacing: 1px; -o-border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; text-shadow: none; background-color: transparent; -webkit-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -moz-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -ms-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -o-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -webkit-box-sizing: initial !important; -moz-box-sizing: initial !important; box-sizing: initial !important; } .vc_grid-container .vc_row.vc_grid .vc_grid-item .vc_btn:hover { background-color: #1abc9c; border-color: #1abc9c; color: #fff !important; text-decoration: none; } .vc_grid-container .vc_row.vc_grid .vc_pageable-load-more-btn .vc_btn { position: relative; display: inline-block; width: auto; height: 39px; line-height: 39px; margin: 0; padding: 0px 23px; border: 2px solid #303030; font-size: 13px; font-weight: 700; font-family: inherit; text-align: left; color: #303030 !important; text-decoration: none; cursor: pointer; white-space: nowrap; outline: none; font-style: normal; text-transform: uppercase; letter-spacing: 1px; -o-border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; text-shadow: none; background-color: transparent; -webkit-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -moz-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -ms-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -o-transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; transition: color 0.1s linear, background-color 0.1s linear,border-color 0.1s linear; -webkit-box-sizing: initial !important; -moz-box-sizing: initial !important; box-sizing: initial !important; } .vc_grid-container .vc_row.vc_grid .vc_pageable-load-more-btn .vc_btn:hover { background-color: #1abc9c; border-color: #1abc9c; color: #fff !important; text-decoration: none; } /* .vc_grid-container .vc_grid-pagination .vc_grid-pagination-list > li > a { position: relative; color: #303030; display: inline-block; width: 38px; height: 38px; line-height: 38px; margin: 0 11px 0 0; text-align:center; color: #b4b4b4 !important; font-size: 18px; text-decoration: none; text-transform: uppercase; cursor: pointer; white-space: nowrap; outline: none; -o-border-radius: 4px !important; -moz-border-radius: 4px !important; -webkit-border-radius: 4px !important; -ms-border-radius: 4px !important; border-radius: 4px !important; text-shadow: none; background-color: transparent !important; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; } */ .vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-square_dots .vc_grid-owl-dot span { border: 2px solid #e5e5e5; background-color: transparent !important; } .vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-square_dots .vc_grid-owl-dot span:hover { background-color: #e3e3e3 !important; border-color: #e3e3e3 !important; } .vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-square_dots .vc_grid-owl-dot.active span { background-color: #e3e3e3 !important; border-color: #e3e3e3 !important; } .vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-radio_dots .vc_grid-owl-dot span { border: 2px solid #e5e5e5; border-radius: 50%; background-color: transparent !important; } .vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-radio_dots .vc_grid-owl-dot span:hover { background-color: #e3e3e3 !important; border-color: #e3e3e3 !important; } .vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-radio_dots .vc_grid-owl-dot.active span { background-color: #e3e3e3 !important; border-color: #e3e3e3 !important; } .vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-point_dots .vc_grid-owl-dot span { background-color: #e3e3e3 !important; } .vc_grid-container .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-fill_square_dots .vc_grid-owl-dot span { background-color: #e3e3e3 !important; } .vc_grid.vc_grid-owl-theme .vc_grid-owl-dots.vc_grid-round_fill_square_dots .vc_grid-owl-dot span { background-color: #e3e3e3 !important; } .vc_grid-container .vc_grid-pagination .vc_grid-pagination-list > li > a { background-color: transparent !important; color: #b4b4b4 !important; -o-border-radius: 4px !important; -moz-border-radius: 4px !important; -webkit-border-radius: 4px !important; -ms-border-radius: 4px !important; border-radius: 4px !important; font-size: 18px; margin: 0 11px 0 0; text-align:center; width: 42px; height: 42px; text-decoration: none; text-transform: uppercase; cursor: pointer; white-space: nowrap; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -ms-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; border: 2px solid #e5e5e5; } .vc_grid-container .vc_grid-pagination .vc_grid-pagination-list > li > a:hover { color: #303030 !important; background-color: #e3e3e3 !important; border-color: #e3e3e3; } .vc_grid-container .vc_grid-pagination .vc_grid-pagination-list > li.vc_grid-active > a { color: #303030 !important; background-color: #e3e3e3 !important; border-color: #e3e3e3; } .vc_grid-container .vc_grid-pagination-list.vc_grid-pagination_rounded_light > li > a, .vc_grid-container .vc_grid-pagination-list.vc_grid-pagination_rounded_dark > li > a, .vc_grid-container .vc_grid-pagination-list.vc_grid-pagination_rounded > li > a { border-radius: 30px !important; } .vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_square > li > a, .vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_square_light > li > a, .vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_square_dark > li > a { line-height: 38px; border-radius: 0 !important; } .vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_stripes_dark > li > a, .vc_grid-container .vc_grid-pagination .vc_grid-pagination-list.vc_grid-pagination_stripes_light > li > a { width: 22px; height: 36px; line-height: 36px; } .vc_grid.vc_row.vc_grid-gutter-30px { margin-bottom: 0 !important; } .vc_grid-container .vc_grid-filter.vc_grid-filter-color-grey > .vc_grid-filter-item { border: none !important; } .vc_grid-container .vc_grid-filter.vc_grid-filter-color-grey > .vc_grid-filter-item:hover, .vc_grid-container .vc_grid-filter.vc_grid-filter-color-grey > .vc_grid-filter-item.vc_active { background: transparent; } /* ========================================================================== End of Visual Composer Grid Elements ============================================================================ */ /* ========================================================================== Start of overlapping content ========================================================================== */ .overlapping_content .title_outer{ position: relative; z-index: 50; /* smaller than the content, so content could be over title */ } .overlapping_content .content > .container{ background-color: #f8f8f8; } .overlapping_content .content .content_inner > .container > .overlapping_content, .overlapping_content .content .content_inner > .full_width > .full_width_inner{ margin-top: -40px; position: relative; z-index: 100; /* greater than the title, so content could be over title */ } .overlapping_content .title .title_holder .container{ padding-bottom: 40px; box-sizing: border-box; } .overlapping_content .content .content_inner > .container{ text-align: center; } .overlapping_content .content .content_inner > .container > .overlapping_content{ display: inline-block; vertical-align: middle; margin-right: auto; margin-left: auto; padding: 0px 40px; background-color: #ffffff; } .transparent_content.overlapping_content .content .content_inner > .container, .transparent_content.overlapping_content .content .content_inner > .full_width > .full_width_inner{ /* full_width_inner because of the negative margin on it */ background-color: #ffffff; } .overlapping_content .content .content_inner > .container > .overlapping_content .overlapping_content_inner{ overflow: hidden; text-align: left; } .overlapping_content_margin{ margin: 0px -40px; display: block; position: relative; } @media only screen and (max-width: 1200px) { .overlapping_content .content .content_inner > .container > .overlapping_content{ padding: 0px 20px !important; } .overlapping_content_margin { margin: 0px -20px !important; } } @media only screen and (max-width: 1000px) { header .overlapping_content_margin { margin: 0px !important; } } /* ========================================================================== End of overlapping content ========================================================================== */ /* ========================================================================== Start blog with next post on bottom ========================================================================== */ .blog_vertical_loop .full_width_inner{ margin: 0px !important; } .blog_vertical_loop article{ position: relative; vertical-align: middle; z-index: 1; /*one after another overlapping*/ margin: 0px 0px 140px 0px; } .blog_vertical_loop article.move_up{ -webkit-transition: transform 450ms ease 0s; transition: transform 450ms ease 0s; } .blog_vertical_loop article.fade_out { opacity: 0; transform: scale(0.8) translate3d(0px, -10%, 0px); transition: all 450ms ease 0s; } .blog_vertical_loop article .post_image{ margin-bottom: 55px !important; height: 400px; } .blog_vertical_loop article .post_image_inner{ height: 100%; overflow: hidden; } .blog_vertical_loop article .post_image_inner a{ position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; background-position: center center; background-repeat: no-repeat; background-size: cover; } .blog_vertical_loop article.previous_post{ position: absolute; opacity: 0; transform: scale(0.8) translate3d(0px, -10%, 0px); } .blog_vertical_loop article.fade_in { transition: all 450ms ease 0s; opacity: 1; transform: scale(1) translate3d(0px, 0px, 0px); } .blog_vertical_loop article.next_post, .blog_vertical_loop article.next_post .post_content_holder .post_image{ margin: 0px !important; } .blog_vertical_loop article.next_post .post_content_holder > .grid_section, .blog_vertical_loop article.next_post .post_content_holder .post_image > .grid_section{ display: none; } .blog_vertical_loop .blog_load_next{ display: none; position: absolute; left: 0; top: -30px; width: 100%; } .blog_vertical_loop article.next_post .blog_load_next{ display: block; } .blog_vertical_loop .blog_load_prev{ display: block; position: absolute; left: 0; bottom: -30px; width: 100%; } .blog_vertical_loop article.next_post .blog_load_prev{ display: none; } .blog_vertical_loop_button{ text-align: left; } .blog_vertical_loop_back_button{ text-align: right; } .blog_vertical_loop_button .button_icon a, .blog_vertical_loop_back_button .button_icon a{ width: 60px; height: 60px; background-color: #303030; display: inline-block; position: relative; text-align: center; border-radius: 50%; -webkit-transition: background-color 0.15s ease-out; -moz-transition: background-color 0.15s ease-out; -ms-transition: background-color 0.15s ease-out; -o-transition: background-color 0.15s ease-out; transition: background-color 0.15s ease-out; } .blog_vertical_loop_button .button_icon a:before, .blog_vertical_loop_back_button .button_icon a:before{ content: '3'; font-family: "ElegantIcons"; font-variant: normal; font-weight: normal; line-height: 60px; text-transform: none; color: #ffffff; font-size: 22px; -webkit-transition: color 0.15s ease-out; -moz-transition: color 0.15s ease-out; -ms-transition: color 0.15s ease-out; -o-transition: color 0.15s ease-out; transition: color 0.15s ease-out; } .blog_vertical_loop_back_button .button_icon a:before{ content: 'J'; } .blog_vertical_loop_button_holder .last_page{ display: none; } .blog_vertical_loop article .post_image_title{ opacity: 0; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 10; display: table; -webkit-transition: all 0.5s ease 0s ; transition: all 0.5s ease 0s; } .blog_vertical_loop article.next_post .post_image_title{ opacity: 1; } .blog_vertical_loop article .post_image_title .post_image_title_inner{ display: table-cell; vertical-align: middle; text-align: center; background-color: rgba(0,0,0,0.6); } .blog_vertical_loop article .post_image_title .post_image_title_inner h2{ color: #ffffff; } .blog_holder.blog_vertical_loop_type{ position: relative; } .blog_holder.blog_vertical_loop_type article:not(.format-quote):not(.format-link) .social_share_list_holder{ margin-top: 15px; } .blog_holder.blog_vertical_loop_type .qbutton.loop_more{ margin: 40px 0px 0px 0px; } .blog_holder.blog_vertical_loop_type article:not(.format-quote):not(.format-link) .post_text .post_text_inner{ background-color: transparent; padding: 0; } .blog_holder.blog_vertical_loop_type article.format-quote .post_text, .blog_holder.blog_vertical_loop_type article.format-link .post_text{ margin-bottom: 30px; } .blog_holder.blog_vertical_loop_type article .post_text h2{ margin-bottom: 35px; } .blog_holder article.blog_vertical_loop_type .post_info{ margin-bottom:8px; } .blog_holder.blog_vertical_loop_type article .post_info > span, .blog_holder.blog_vertical_loop_type article .post_info > div { padding-right: 20px; position: relative; float: left; } .blog_holder.blog_vertical_loop_type article .post_info > span:last-child, .blog_holder.blog_vertical_loop_type article .post_info > div:last-child{ padding-right: 0px; } .blog_holder.blog_vertical_loop_type article .post_info > span:after, .blog_holder.blog_vertical_loop_type article .post_info > div:after { position: absolute; right: 5px; top: 0; content: "/"; } .blog_holder.blog_vertical_loop_type article .post_info > span:last-child:after, .blog_holder.blog_vertical_loop_type article .post_info > div:last-child:after { content: ""; } .blog_holder.blog_vertical_loop_type .blog_like a { line-height: inherit; } /* ========================================================================== End blog with next post on bottom ========================================================================== */ /* ========================================================================== Start of Parallax Layers ============================================================================ */ .qode_parallax_layers{ width: 100%; height: 500px; position: relative; overflow: hidden; } .qode_parallax_layers_holder{ position: relative; width: 110%; height: 110%; top: -5%; left: -5%; } .qode_parallax_layers_holder .image{ position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; background-size: cover; background-position: center center; transform: translateZ(0px); -webkit-transform: translateZ(0px); } .qode_parallax_layers_holder .paralax_layers_content_holder{ position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; } .qode_parallax_layers_holder .paralax_layers_content{ display: table; width: 100%; height: 100%; } .qode_parallax_layers_holder .paralax_layers_content_inner{ display: table-cell; vertical-align: middle; width: 100%; height: 100%; text-align: center; } /* ========================================================================== End of Parallax Layers ============================================================================ */ ================================================ FILE: core/jdiameter/api/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter jdiameter-core 2.5.1-SNAPSHOT ../pom.xml jdiameter-api Quarkus :: JDiameter Stack :: API ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Answer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * An Answer message is sent by a recipient of Request once it has received and interpreted the Request. Answers contain * a Result-Code AVP and other AVPs in message body. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Answer extends Message { /** * @return ResultCode Avp from message */ Avp getResultCode(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ApplicationAlreadyUseException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * The ApplicationAlreadyUse signals that the application a user is reporting support for is already in use by someone * else. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public class ApplicationAlreadyUseException extends Exception { private static final long serialVersionUID = 1L; /** * Constructor with reason string * * @param message reason string */ public ApplicationAlreadyUseException(String message) { super(message); } /** * Constructor with reason string and parent exception * * @param message message reason string * @param cause parent exception */ public ApplicationAlreadyUseException(String message, Throwable cause) { super(message, cause); } /** * Constructor with parent exception * * @param cause parent exception */ public ApplicationAlreadyUseException(Throwable cause) { super(cause); } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ApplicationId.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.io.Serial; import java.io.Serializable; /** * The application Id is used to point out an application that is supported or used. It is a combination of * Authentication application id, Accounting application id and Vendor id. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ public final class ApplicationId implements Serializable { @Serial private static final long serialVersionUID = 1L; /** * Undefined value of id for application identifier */ public static final long UNDEFINED_VALUE = 0x0; /** * Standards-track application IDs are by Designated Expert with Specification Required [IANA] */ @SuppressWarnings("all") //3rd party lib public interface Standard { long DIAMETER_COMMON_MESSAGE = 0x0; long NASREQ = 0x1; long MOBILE_IP = 0x2; long DIAMETER_BASE_ACCOUNTING = 0x3; long RELAY = 0xffffffff; } /** * IANA [IANA] has assigned the range 0x00000001 to 0x00ffffff for standards-track applications; and 0x01000000 - * 0xfffffffe for vendor specific applications, on a first-come, first-served basis. The following values are * allocated. */ @SuppressWarnings("all") //3rd party lib public interface Ranges { long STANDARDS_TRACK_APPLICATIONS_MIN = 0x00000001; long STANDARDS_TRACK_APPLICATIONS_MAX = 0x00ffffff; long VENDOR_SPECIFIC_APPLICATIONS_MIN = 0x01000000; long VENDOR_SPECIFIC_APPLICATIONS_MAX = 0xfffffffe; } private long venId; private long authId; private long acctId; /** * Create instance of ApplicationId use Authentication-App-Id * * @param authAppId authentication application id * @return instance of class */ public static ApplicationId createByAuthAppId(long authAppId) { return new ApplicationId(UNDEFINED_VALUE, authAppId, UNDEFINED_VALUE); } /** * Create instance of ApplicationId use Accounting-Applicaion-Id * * @param acchAppId accounting applicaion Id * @return instance of class */ public static ApplicationId createByAccAppId(long acchAppId) { return new ApplicationId(UNDEFINED_VALUE, UNDEFINED_VALUE, acchAppId); } /** * Create instance of ApplicationId use Authentication-App-Id and Vendor-Id * * @param vendorId vendor specific id * @param authAppId authentication application id * @return instance of class */ public static ApplicationId createByAuthAppId(long vendorId, long authAppId) { return new ApplicationId(vendorId, authAppId, UNDEFINED_VALUE); } /** * Create instance of ApplicationId use Accounting-Applicaion-Id and Vendor-Id * * @param vendorId vendor specific id * @param acchAppId accounting applicaion Id * @return instance of class */ public static ApplicationId createByAccAppId(long vendorId, long acchAppId) { return new ApplicationId(vendorId, UNDEFINED_VALUE, acchAppId); } /** * Create instance * * @param vendorId vendor specific id * @param authAppId authentication application id * @param acctAppId accounting applicaion Id */ private ApplicationId(long vendorId, long authAppId, long acctAppId) { this.authId = authAppId; this.acctId = acctAppId; this.venId = vendorId; } /** * @return Vendor-Isd */ public long getVendorId() { return venId; } /** * @return Authentication-Application-Id */ public long getAuthAppId() { return authId; } /** * @return Accounting-Application-Id */ public long getAcctAppId() { return acctId; } /** * @param obj check object * @return true if check object equals current instance (all appId is equals) */ @Override public boolean equals(Object obj) { if (obj instanceof ApplicationId) { ApplicationId appId = (ApplicationId) obj; return authId == appId.authId && acctId == appId.acctId && venId == appId.venId; } else { return false; } } /** * @return hash code of object */ @Override public int hashCode() { int result; result = (int) (venId ^ (venId >>> 32)); result = 31 * result + (int) (authId ^ (authId >>> 32)); result = 31 * result + (int) (acctId ^ (acctId >>> 32)); return result; } /** * @return String representation of object */ @Override public String toString() { return new StringBuffer("AppId [").append("Vendor-Id:").append(venId).append("; Auth-Id:").append(authId) .append("; Acct-Id:").append(acctId).append("]").toString(); } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Avp.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.io.Serializable; import java.net.InetAddress; import java.util.Date; /** * The Avp class implements a Diameter AVP. This class allows applications to build and read arbitrary Diameter AVP * objects. Wrapper interface allows adapt message to any driver vendor specific interface Serializable interface allows * use this class in SLEE Event objects * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @author
      Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Avp extends Wrapper, Serializable { /** * The Accounting-Realtime-Required AVP code */ int ACCOUNTING_REALTIME_REQUIRED = 483; /** * The Auth-Request-Type AVP code */ int AUTH_REQUEST_TYPE = 274; /** * The Authorization-Lifetime AVP code */ int AUTHORIZATION_LIFETIME = 291; /** * The Auth-Grace-Period AVP code */ int AUTH_GRACE_PERIOD = 276; /** * The Auth-Session-State AVP code */ int AUTH_SESSION_STATE = 277; /** * The Class AVP code */ int CLASS = 25; /** * The E2E-Sequence-Avp AVP code */ int E2E_SEQUENCE_AVP = 300; /** * The Error-reporting-host AVP code */ int ERROR_REPORTING_HOST = 294; /** * The Event-Timestamp AVP code */ int EVENT_TIMESTAMP = 55; /** * The File-Avp AVP code */ int FAILED_AVP = 279; /** * The Acct-Interim-Interval AVP code */ int ACCT_INTERIM_INTERVAL = 85; /** * The User-Name AVP code */ int USER_NAME = 1; /** * The Result-Code AVP code */ int RESULT_CODE = 268; /** * Experimental-Result AVP code */ int EXPERIMENTAL_RESULT = 297; /** * The Experimental-Result-Code AVP code */ int EXPERIMENTAL_RESULT_CODE = 298; /** * The Termination-Cause AVP code */ int TERMINATION_CAUSE = 295; /** * The FirmWare-Revision AVP code */ int FIRMWARE_REVISION = 267; /** * The Host-IP-Address AVP code */ int HOST_IP_ADDRESS = 257; /** * The Muti-Round-Timeout AVP code */ int MULTI_ROUND_TIMEOUT = 272; /** * The Origin-Host AVP code */ int ORIGIN_HOST = 264; /** * The Origin-Realm AVP code */ int ORIGIN_REALM = 296; /** * The Origin-State-Id AVP code */ int ORIGIN_STATE_ID = 278; /** * The Redirect-Host AVP code */ int REDIRECT_HOST = 292; /** * The Redirect-Host-Usage AVP code */ int REDIRECT_HOST_USAGE = 261; /** * The Redirect-Max-Cache-Time AVP code */ int REDIRECT_MAX_CACHE_TIME = 262; /** * The Product-Name AVP code */ int PRODUCT_NAME = 269; /** * The Session-Id AVP code */ int SESSION_ID = 263; /** * The Session-Timeout AVP code */ int SESSION_TIMEOUT = 27; /** * The Session-Binding AVP code */ int SESSION_BINDING = 270; /** * The Session-Server-Failover AVP code */ int SESSION_SERVER_FAILOVER = 271; /** * The Destination-Host AVP code */ int DESTINATION_HOST = 293; /** * The Destination-Realm AVP code */ int DESTINATION_REALM = 283; /** * The Route-Record AVP code */ int ROUTE_RECORD = 282; /** * The Proxy-Info AVP code */ int PROXY_INFO = 284; /** * The Proxy-Host AVP code */ int PROXY_HOST = 280; /** * The Proxy-State AVP code */ int PROXY_STATE = 33; /** * The Authentication-Application-Id AVP code */ int AUTH_APPLICATION_ID = 258; /** * The Accounting-Application-Id AVP code */ int ACCT_APPLICATION_ID = 259; /** * The Inband-Security-Id AVP code */ int INBAND_SECURITY_ID = 299; /** * The Vendor-Id AVP code */ int VENDOR_ID = 266; /** * The Supported-Vendor-Id AVP code */ int SUPPORTED_VENDOR_ID = 265; /** * The Vendor-Specific-Application-Id AVP code */ int VENDOR_SPECIFIC_APPLICATION_ID = 260; /** * The Re-Authentication-Request-type AVP code */ int RE_AUTH_REQUEST_TYPE = 285; /** * The Accounting-Record-Type AVP code */ int ACC_RECORD_TYPE = 480; /** * The Accounting-Record-Number AVP code */ int ACC_RECORD_NUMBER = 485; /** * The Accounting-Session-Id AVP code */ int ACC_SESSION_ID = 44; /** * The Accounting-Sub-Session-Id AVP code */ int ACC_SUB_SESSION_ID = 287; /** * The Accounting-Multi-Session-Id AVP code */ int ACC_MULTI_SESSION_ID = 50; /** * The Disconnect cause AVP code */ int DISCONNECT_CAUSE = 273; /** * The Error-Message AVP code */ int ERROR_MESSAGE = 281; // RFC 4006 (Credit-Control-Application) AVPs /** * CCA (RFC4006) Correlation ID AVP code */ int CC_CORRELATION_ID = 411; /** * CCA (RFC4006) Credit Control Input Octets AVP code */ int CC_INPUT_OCTETS = 412; /** * CCA (RFC4006) Credit Control Money AVP code */ int CC_MONEY = 413; /** * CCA (RFC4006) Credit Control Output Octets AVP code */ int CC_OUTPUT_OCTETS = 414; /** * CCA (RFC4006) Credit Control Request Number AVP code */ int CC_REQUEST_NUMBER = 415; /** * CCA (RFC4006) Request Type AVP code */ int CC_REQUEST_TYPE = 416; /** * CCA (RFC4006) Credit Control Service Specific Units AVP code */ int CC_SERVICE_SPECIFIC_UNITS = 417; /** * CCA (RFC4006) Credit Control Session Failover AVP code */ int CC_SESSION_FAILOVER = 418; /** * CCA (RFC4006) Credit Control Sub Session ID AVP code */ int CC_SUB_SESSION_ID = 419; /** * CCA (RFC4006) Credit Control Time AVP code */ int CC_TIME = 420; /** * CCA (RFC4006) Credit Control Total Octets AVP code */ int CC_TOTAL_OCTETS = 421; /** * CCA (RFC4006) Credit Control Unit Type AVP code */ int CC_UNIT_TYPE = 454; /** * CCA (RFC4006) Check Balance result AVP code */ int CHECK_BALANCE_RESULT = 422; /** * CCA (RFC4006) Cost Information AVP code */ int COST_INFORMATION = 423; /** * CCA (RFC4006) Cost Unit AVP code */ int COST_UNIT = 424; /** * CCA (RFC4006) Currency Code AVP code */ int CURRENCY_CODE = 425; /** * CCA (RFC4006) Credit Control AVP code */ int CREDIT_CONTROL = 426; /** * CCA (RFC4006) Credit Control Failure Handling AVP code */ int CREDIT_CONTROL_FAILURE_HANDLING = 427; /** * CCA (RFC4006) Direct Debiting Failure Handling AVP code */ int DIRECT_DEBITING_FAILURE_HANDLING = 428; /** * CCA (RFC4006) Exponent AVP code */ int EXPONENT = 429; /** * CCA (RFC4006) Final Unit Action AVP code */ int FINAL_UNIT_ACTION = 449; /** * CCA (RFC4006) Final Unit Indication AVP code */ int FINAL_UNIT_INDICATION = 430; /** * CCA (RFC4006) Granted Service Unit AVP code */ int GRANTED_SERVICE_UNIT = 431; /** * CCA (RFC4006) GSU Pool Identifier AVP code */ int GSU_POOL_ID = 453; /** * CCA (RFC4006) GSU Pool Reference AVP code */ int GSU_POOL_REFERENCE = 457; /** * CCA (RFC4006) Multiple Services Credit Control AVP code */ int MULTIPLE_SERVICES_CREDIT_CONTROL = 456; /** * CCA (RFC4006) Multiple Services Indicator AVP code */ int MULTIPLE_SERVICES_INDICATOR = 455; /** * CCA (RFC4006) Rating Group AVP code */ int RATING_GROUP = 432; /** * CCA (RFC4006) Redirect Address Type AVP code */ int REDIRECT_ADDRESS_TYPE = 433; /** * CCA (RFC4006) Redirect Server AVP code */ int REDIRECT_SERVER = 434; /** * CCA (RFC4006) Redirect Address AVP code */ int REDIRECT_ADDRESS = 435; /** * CCA (RFC4006) Requested Action AVP code */ int REQUESTED_ACTION = 436; /** * CCA (RFC4006) Requested Service Unit AVP code */ int REQUESTED_SERVICE_UNIT = 437; /** * CCA (RFC4006) Restriction Filter Rule AVP code */ int RESTRICTION_FILTER_RULE = 438; /** * CCA (RFC4006) Service Context Id AVP code */ int SERVICE_CONTEXT_ID = 461; /** * CCA (RFC4006) Service Id AVP code */ int SERVICE_IDENTIFIER_CCA = 439; /** * CCA (RFC4006) Service Parameter Info AVP code */ int SERVICE_PARAMETER_INFO = 440; /** * CCA (RFC4006) Service Parameter Type AVP code */ int SERVICE_PARAMETER_TYPE = 441; /** * CCA (RFC4006) Service Parameter Value AVP code */ int SERVICE_PARAMETER_VALUE = 442; /** * CCA (RFC4006) Subscription Id AVP code */ int SUBSCRIPTION_ID = 443; /** * CCA (RFC4006) Subscription Id Data AVP code */ int SUBSCRIPTION_ID_DATA = 444; /** * CCA (RFC4006) Subscription Id Type AVP code */ int SUBSCRIPTION_ID_TYPE = 450; /** * CCA (RFC4006) Tariff Change Usage AVP code */ int TARIFF_CHANGE_USAGE = 452; /** * CCA (RFC4006) Tariff Time Change AVP code */ int TARIFF_TIME_CHANGE = 451; /** * CCA (RFC4006) Unit Value AVP code */ int UNIT_VALUE = 445; /** * CCA (RFC4006) Used Service Unit AVP code */ int USED_SERVICE_UNIT = 446; /** * CCA (RFC4006) User Equipment Info AVP code */ int USER_EQUIPMENT_INFO = 458; /** * CCA (RFC4006) User Equipment Info Type AVP code */ int USER_EQUIPMENT_INFO_TYPE = 459; /** * CCA (RFC4006) User Equipment Info Value AVP code */ int USER_EQUIPMENT_INFO_VALUE = 460; /** * CCA (RFC4006) Value Digits AVP code */ int VALUE_DIGITS = 447; /** * CCA (RFC4006) Validity Time AVP code */ int VALIDITY_TIME = 448; // Cx/Dx IMS Interface AVPs /** * Cx/Dx (3GPP TS 29.229) Visited Network Identifier AVP code */ int VISITED_NETWORK_ID = 600; /** * Cx/Dx (3GPP TS 29.229) Public Identity AVP code */ int PUBLIC_IDENTITY = 601; /** * Cx/Dx (3GPP TS 29.229) Server Name AVP code */ int SERVER_NAME = 602; /** * Cx/Dx (3GPP TS 29.229) Server Capabilities AVP code */ int SERVER_CAPABILITIES = 603; /** * Cx/Dx (3GPP TS 29.229) Mandatory Capability AVP code */ int MANDATORY_CAPABILITY = 604; /** * Cx/Dx (3GPP TS 29.229) Optional Capability AVP code */ int OPTIONAL_CAPABILITY = 605; /** * Cx/Dx (3GPP TS 29.229) UserData AVP code */ int USER_DATA_CXDX = 606; // why the hell there is double def, is 3GPP sane? /** * Cx/Dx (3GPP TS 29.229) SIP Number Auth Items AVP code */ int SIP_NUMBER_AUTH_ITEMS = 607; /** * Cx/Dx (3GPP TS 29.229) SIP Authentication Scheme AVP code */ int SIP_AUTHENTICATION_SCHEME = 608; /** * Cx/Dx (3GPP TS 29.229) SIP Authenticate AVP code */ int SIP_AUTHENTICATE = 609; /** * Cx/Dx (3GPP TS 29.229) SIP Authorization AVP code */ int SIP_AUTHORIZATION = 610; /** * Cx/Dx (3GPP TS 29.229) SIP Authentication Context AVP code */ int SIP_AUTHENTICATION_CONTEXT = 611; /** * Cx/Dx (3GPP TS 29.229) SIP Auth Data Item AVP code */ int SIP_AUTH_DATA_ITEM = 612; /** * Cx/Dx (3GPP TS 29.229) SIP Item Number AVP code */ int SIP_ITEM_NUMBER = 613; /** * Cx/Dx (3GPP TS 29.229) Server Assignment Type AVP code */ int SERVER_ASSIGNMENT_TYPE = 614; /** * Cx/Dx (3GPP TS 29.229) Deregistration Reason AVP code */ int DEREGISTRATION_REASON = 615; /** * Cx/Dx (3GPP TS 29.229) Reason Code AVP code */ int REASON_CODE = 616; /** * Cx/Dx (3GPP TS 29.229) Reason Info AVP code */ int REASON_INFO = 617; /** * Cx/Dx (3GPP TS 29.229) Charging Information AVP code */ int CHARGING_INFORMATION = 618; /** * Cx/Dx (3GPP TS 29.229) Primary Event Charging Function Name AVP code */ int PRI_EVENT_CHARGING_FUNCTION = 619; /** * Cx/Dx (3GPP TS 29.229) Secondary Event Charging Function Name AVP code */ int SEC_EVENT_CHARGING_FUNCTION = 620; /** * Cx/Dx (3GPP TS 29.229) Primary Charging Collection Function Name AVP code */ int PRI_CHARGING_COLLECTION_FUNCTION = 621; /** * Cx/Dx (3GPP TS 29.229) Secondary Charging Collection Function Name AVP code */ int SEC_CHARGING_COLLECTION_FUNCTION = 622; /** * Cx/Dx (3GPP TS 29.229) User Authorization Type AVP code */ int USER_AUTORIZATION_TYPE = 623; /** * Cx/Dx (3GPP TS 29.229) User Data Already Available AVP code */ int USER_DATA_ALREADY_AVAILABLE = 624; /** * Cx/Dx (3GPP TS 29.229) Confidentiality Key AVP code */ int CONFIDENTIALITY_KEY = 625; /** * Cx/Dx (3GPP TS 29.229) Integrity Key AVP code */ int INTEGRITY_KEY = 626; /** * Supported Features AVP code */ int SUPPORTED_FEATURES = 628; /** * Cx/Dx (3GPP TS 29.229) Feature List ID AVP code */ int FEATURE_LIST_ID = 629; /** * Cx/Dx (3GPP TS 29.229) Feature List AVP code */ int FEATURE_LIST = 630; /** * Cx/Dx (3GPP TS 29.229) Supported Applications AVP code */ int SUPPORTED_APPLICATIONS = 631; /** * Cx/Dx (3GPP TS 29.229) Associated Identities AVP code */ int ASSOCAITED_IDENTITIES = 632; /** * Cx/Dx (3GPP TS 29.229) originating Request AVP code */ int ORIGINATING_REQUEST = 633; /** * Wildcarded PSI AVP code */ int WILDCARDED_PSI = 634; /** * Cx/Dx (3GPP TS 29.229) SIP Digest Authenticate AVP code */ int SIP_DIGEST_AUTHENTICATE = 635; /** * Wildcarded IMPU AVP code */ int WILDCARDED_IMPU = 636; /** * Cx/Dx (3GPP TS 29.229) UAR Flags AVP code */ int UAR_FLAGS = 637; /** * Cx/Dx (3GPP TS 29.229) Loose Route Indication AVP code */ int LOOSE_ROUTE_INDICATION = 638; /** * Cx/Dx (3GPP TS 29.229) SCSCF Restoration Info AVP code */ int SCSCF_RESTORATION_INFO = 639; /** * Cx/Dx (3GPP TS 29.229) Path AVP code */ int PATH = 640; /** * Cx/Dx (3GPP TS 29.229) Contact AVP code */ int CONTACT = 641; /** * Cx/Dx (3GPP TS 29.229) Subscription Info AVP code */ int SUBSCRIPTION_INFO = 642; /** * Cx/Dx (3GPP TS 29.229) Call ID SIP Header AVP code */ int CALL_ID_SIP_HEADER = 643; /** * Cx/Dx (3GPP TS 29.229) From SIP Header AVP code */ int FROM_SIP_HEADER = 644; /** * Cx/Dx (3GPP TS 29.229) To SIP Header AVP code */ int TO_SIP_HEADER = 645; /** * Cx/Dx (3GPP TS 29.229) Record Route AVP code */ int RECORD_ROUTE = 646; /** * Cx/Dx (3GPP TS 29.229) Associated Registered Identities AVP code */ int ASSOCIATED_REGISTERED_IDENTITIES = 647; /** * Cx/Dx (3GPP TS 29.229) Multiple Registration Indication AVP code */ int MULTIPLE_REGISTRATION_INDICATION = 648; /** * Cx/Dx (3GPP TS 29.229) Restoration Info AVP code */ int RESTORATION_INFO = 649; // Sh IMS Interface AVPs /** * Sh (3GPP TS 29.329) User Identity AVP code */ int USER_IDENTITY = 700; /** * Sh (3GPP TS 29.329) User Data AVP code */ int USER_DATA_SH = 702; /** * Sh (3GPP TS 29.329) Data Reference AVP code */ int DATA_REFERENCE = 703; /** * Sh (3GPP TS 29.329) Service Indication AVP code */ int SERVICE_INDICATION = 704; /** * Sh (3GPP TS 29.329) Subs Req Type AVP code */ int SUBS_REQ_TYPE = 705; /** * Sh (3GPP TS 29.329) Requested Domain AVP code */ int REQUESTED_DOMAIN = 706; /** * Sh (3GPP TS 29.329) Current Location AVP code */ int CURRENT_LOCATION = 707; /** * Sh (3GPP TS 29.329) identity Set AVP code */ int IDENTITY_SET = 708; /** * Sh (3GPP TS 29.329) Expiry Time AVP code */ int EXPIRY_TIME = 709; /** * Sh (3GPP TS 29.329) Send Data Indication AVP code */ int SEND_DATA_INDICATION = 710; /** * Sh (3GPP TS 29.329) DSAI Tag AVP code */ int DSAI_TAG = 711; // Ro/Rf IMS Interfaces AVPs /** * Ro/Rf (3GPP TS 32.299) Low Balance Indication AVP code */ int LOW_BALANCE_INDICATION = 2020; /** * Ro/Rf (3GPP TS 32.299) 3GPP Charging Characteristics AVP code */ int TGPP_CHARGING_CHARACTERISTICS = 13; /** * Ro/Rf (3GPP TS 32.299) 3GPP Charging Id AVP code */ int TGPP_CHARGING_ID = 2; /** * Ro/Rf (3GPP TS 32.299) 3GPP GGSN MCC MNC AVP code */ int TGPP_GGSN_MCC_MNC = 9; /** * Ro/Rf (3GPP TS 32.299) 3GPP IMSI AVP code */ int TGPP_IMSI = 1; /** * Ro/Rf (3GPP TS 32.299) 3GPP IMSI MCC MNC AVP code */ int TGPP_IMSI_MCC_MNC = 8; /** * Ro/Rf (3GPP TS 32.299) 3GPP MS TimeZone AVP code */ int TGPP_MS_TIMEZONE = 23; /** * Ro/Rf (3GPP TS 32.299) 3GPP NSAPI AVP code */ int TGPP_NSAPI = 10; /** * Ro/Rf (3GPP TS 32.299) 3GPP PDP Type AVP code */ int TGPP_PDP_TYPE = 3; /** * Ro/Rf (3GPP TS 32.299) 3GPP RAT Type AVP code */ int TGPP_RAT_TYPE = 21; /** * Ro/Rf (3GPP TS 32.299) 3GPP Selection Mode AVP code */ int TGPP_SELECTION_MODE = 12; /** * Ro/Rf (3GPP TS 32.299) 3GPP Session Stop Indicator AVP code */ int TGPP_SESSION_STOP_INDICATOR = 11; /** * Ro/Rf (3GPP TS 32.299) 3GPP SGSN MCC MNC AVP code */ int GPP_SGSN_MCC_MNC = 18; /** * Ro/Rf (3GPP TS 32.299) 3GPP User Location Info AVP code */ int GPP_USER_LOCATION_INFO = 22; /** * Ro/Rf (3GPP TS 32.299) 3GPP2 BSID AVP code */ int TGPP2_BSID = 5535; /** * Ro/Rf (3GPP TS 32.299) Access Network Charging Identifier Value AVP code */ int ACCESS_NETWORK_CHARGING_IDENTIFIER_VALUE = 503; /** * Ro/Rf (3GPP TS 32.299) Access Network Information AVP code */ int ACCESS_NETWORK_INFORMATION = 1263; /** * Ro/Rf (3GPP TS 32.299) Accumulated Cost AVP code */ int ACCUMULATED_COST = 2052; /** * Ro/Rf (3GPP TS 32.299) Adaptations AVP code */ int ADAPTATIONS = 1217; /** * Ro/Rf (3GPP TS 32.299) Additional Content Information AVP code */ int ADDITIONAL_CONTENT_INFORMATION = 1207; /** * Ro/Rf (3GPP TS 32.299) Additional Type Information AVP code */ int ADDITIONAL_TYPE_INFORMATION = 1205; /** * Ro/Rf (3GPP TS 32.299) Address Data AVP code */ int ADDRESS_DATA = 897; /** * Ro/Rf (3GPP TS 32.299) Address Domain AVP code */ int ADDRESS_DOMAIN = 898; /** * Ro/Rf (3GPP TS 32.299) Addressee Type AVP code */ int ADDRESSEE_TYPE = 1208; /** * Ro/Rf (3GPP TS 32.299) Address Type AVP code */ int ADDRESS_TYPE = 899; /** * Ro/Rf (3GPP TS 32.299) AF Charging Identifier AVP code */ int AF_CHARGING_IDENTIFIER = 505; /** * Ro/Rf (3GPP TS 32.299) AF Correlation Information AVP code */ int AF_CORRELATION_INFORMATION = 1276; /** * Ro/Rf (3GPP TS 32.299) Allocation Retention Priority AVP code */ int ALLOCATION_RETENTION_PRIORITY = 1034; /** * Ro/Rf (3GPP TS 32.299) Alternate Charged Party Address AVP code */ int ALTERNATE_CHARGED_PARTY_ADDRESS = 1280; /** * Gx/Gxx (3GPP TS 29.212) APN aggregate max bitrate DL AVP code */ int APN_AGGREGATE_MAX_BITRATE_DL = 1040; /** * Gx/Gxx (3GPP TS 29.212) APN aggregate max bitrate UL AVP code */ int APN_AGGREGATE_MAX_BITRATE_UL = 1041; /** * Ro/Rf (3GPP TS 32.299) AoC Cost Information AVP code */ int AOC_COST_INFORMATION = 2053; /** * Ro/Rf (3GPP TS 32.299) AoC Information AVP code */ int AOC_INFORMATION = 2054; /** * Ro/Rf (3GPP TS 32.299) AoC Request Type AVP code */ int AOC_REQUEST_TYPE = 2055; /** * Ro/Rf (3GPP TS 32.299) Application provided called party address AVP code */ int APPLICATION_PROVIDED_CALLED_PARTY_ADDRESS = 837; /** * Ro/Rf (3GPP TS 32.299) Application Server AVP code */ int APPLICATION_SERVER = 836; /** * Ro/Rf (3GPP TS 32.299) Application Server ID AVP code */ int APPLICATION_SERVER_ID = 2101; /** * Ro/Rf (3GPP TS 32.299) Application Server Information AVP code */ int APPLICATION_SERVER_INFORMATION = 850; /** * Ro/Rf (3GPP TS 32.299) Application Service Type AVP code */ int APPLICATION_SERVICE_TYPE = 2102; /** * Ro/Rf (3GPP TS 32.299) Application Session ID AVP code */ int APPLICATION_SESSION_ID = 2103; /** * Ro/Rf (3GPP TS 32.299) Applic ID AVP code */ int APPLIC_ID = 1218; /** * Ro/Rf (3GPP TS 32.299) Associated Party Address AVP code */ int ASSOCIATED_PARTY_ADDRESS = 2035; /** * Ro/Rf (3GPP TS 32.299) Associated URI AVP code */ int ASSOCIATED_URI = 856; /** * Ro/Rf (3GPP TS 32.299) Authorized QoS AVP code */ int AUTHORIZED_QOS = 849; /** * Ro/Rf (3GPP TS 32.299) Aux Applic Info AVP code */ int AUX_APPLIC_INFO = 1219; /** * Ro/Rf (3GPP TS 32.299) Base Time Interval AVP code */ int BASE_TIME_INTERVAL = 1265; /** * Gx/Gxx (3GPP TS 29.212) Bearer Identifier AVP code */ int BEARER_IDENTIFIER = 1020; /** * Ro/Rf (3GPP TS 32.299) Bearer Service AVP code */ int BEARER_SERVICE = 854; /** * Ro/Rf (3GPP TS 32.299) Called Asserted Identity AVP code */ int CALLED_ASSERTED_IDENTITY = 1250; /** * Ro/Rf (3GPP TS 32.299) Called Party Address AVP code */ int CALLED_PARTY_ADDRESS = 832; int CALLED_STATION_ID = 30; /** * Ro/Rf (3GPP TS 32.299) Calling Party Address AVP code */ int CALLING_PARTY_ADDRESS = 831; /** * Ro/Rf (3GPP TS 32.299) Carrier Select Routing Information AVP code */ int CARRIER_SELECT_ROUTING_INFORMATION = 2023; /** * Ro/Rf (3GPP TS 32.299) Cause Code AVP code */ int CAUSE_CODE = 861; /** * Ro/Rf (3GPP TS 32.299) CG Address AVP code */ int CG_ADDRESS = 846; /** * Ro/Rf (3GPP TS 32.299) Change Condition AVP code */ int CHANGE_CONDITION = 2037; /** * Ro/Rf (3GPP TS 32.299) Change Time AVP code */ int CHANGE_TIME = 2038; /** * Ro/Rf (3GPP TS 32.299) Charged Party AVP code */ int CHARGED_PARTY = 857; /** * Ro/Rf (3GPP TS 32.299) Charging Rule Base Name AVP code */ int CHARGING_RULE_BASE_NAME = 1004; /** * Ro/Rf (3GPP TS 32.299) Class Identifier AVP code */ int CLASS_IDENTIFIER = 1214; /** * Ro/Rf (3GPP TS 32.299) Client Address AVP code */ int CLIENT_ADDRESS = 2018; /** * Ro/Rf (3GPP TS 32.299) Content Class AVP code */ int CONTENT_CLASS = 1220; /** * Ro/Rf (3GPP TS 32.299) Content Disposition AVP code */ int CONTENT_DISPOSITION = 828; /** * Ro/Rf (3GPP TS 32.299) Content ID AVP code */ int CONTENT_ID = 2116; /** * Ro/Rf (3GPP TS 32.299) Content Provider ID AVP code */ int CONTENT_PROVIDER_ID = 2117; /** * Ro/Rf (3GPP TS 32.299) Content Length AVP code */ int CONTENT_LENGTH = 827; /** * Ro/Rf (3GPP TS 32.299) Content Size AVP code */ int CONTENT_SIZE = 1206; /** * Ro/Rf (3GPP TS 32.299) Content Type AVP code */ int CONTENT_TYPE = 826; /** * Ro/Rf (3GPP TS 32.299) Current Tariff AVP code */ int CURRENT_TARIFF = 2056; /** * Ro/Rf (3GPP TS 32.299) Data Coding Scheme AVP code */ int DATA_CODING_SCHEME = 2001; /** * Ro/Rf (3GPP TS 32.299) DCD Information AVP code */ int DCD_INFORMATION = 2115; /** * Ro/Rf (3GPP TS 32.299) Deferred Location Event Type AVP code */ int DEFERRED_LOCATION_EVENT_TYPE = 1230; /** * Ro/Rf (3GPP TS 32.299) Delivery Report Requested AVP code */ int DELIVERY_REPORT_REQUESTED = 1216; /** * Ro/Rf (3GPP TS 32.299) Delivery Status AVP code */ int DELIVERY_STATUS = 2104; /** * Ro/Rf (3GPP TS 32.299) Destination Interface AVP code */ int DESTINATION_INTERFACE = 2002; /** * Ro/Rf (3GPP TS 32.299) Diagnostics AVP code */ int DIAGNOSTICS = 2039; /** * Ro/Rf (3GPP TS 32.299) Domain Name AVP code */ int DOMAIN_NAME = 1200; /** * Ro/Rf (3GPP TS 32.299) DRM Content AVP code */ int DRM_CONTENT = 1221; /** * Ro/Rf (3GPP TS 32.299) Dynamic Address Flag AVP code */ int DYNAMIC_ADDRESS_FLAG = 2051; /** * Ro/Rf (3GPP TS 32.299) Early Media Description AVP code */ int EARLY_MEDIA_DESCRIPTION = 1272; /** * Ro/Rf (3GPP TS 32.299) Envelope AVP code */ int ENVELOPE = 1266; /** * Ro/Rf (3GPP TS 32.299) Envelope End Time AVP code */ int ENVELOPE_END_TIME = 1267; /** * Ro/Rf (3GPP TS 32.299) Envelope Reporting AVP code */ int ENVELOPE_REPORTING = 1268; /** * Ro/Rf (3GPP TS 32.299) Envelope Start Time AVP code */ int ENVELOPE_START_TIME = 1269; /** * Ro/Rf (3GPP TS 32.299) Event AVP code */ int EVENT = 825; /** * Ro/Rf (3GPP TS 32.299) Event Charging TimeStamp AVP code */ int EVENT_CHARGING_TIMESTAMP = 1258; /** * Ro/Rf (3GPP TS 32.299) Event Type AVP code */ int EVENT_TYPE = 823; /** * Ro/Rf (3GPP TS 32.299) Expires AVP code */ int EXPIRES = 888; /** * Ro/Rf (3GPP TS 32.299) File Repair Supported AVP code */ int FILE_REPAIR_SUPPORTED = 1224; /** * Ro/Rf (3GPP TS 32.299) Flows AVP code */ int FLOWS = 510; /** * Ro/Rf (3GPP TS 32.299) GGSN Address AVP code */ int GGSN_ADDRESS = 847; /** * Ro/Rf (3GPP TS 32.299) Guaranteed Bitrate UL AVP code */ int GUARANTEED_BITRATE_UL = 1026; /** * Ro/Rf (3GPP TS 32.299) Guaranteed Bitrate UL AVP code */ int GUARANTEED_BITRATE_DL = 1025; /** * Ro/Rf (3GPP TS 32.299) IM Information AVP code */ int IM_INFORMATION = 2110; /** * Ro/Rf (3GPP TS 32.299) IMS Charging Identifier AVP code */ int IMS_CHARGING_IDENTIFIER = 841; /** * Ro/Rf (3GPP TS 32.299) IMS Communication Service Identifier AVP code */ int IMS_COMMUNICATION_SERVICE_IDENTIFIER = 1281; /** * Ro/Rf (3GPP TS 32.299) IMS Information AVP code */ int IMS_INFORMATION = 876; /** * Ro/Rf (3GPP TS 32.299) Incoming Trunk Group Id AVP code */ int INCOMING_TRUNK_GROUP_ID = 852; /** * Ro/Rf (3GPP TS 32.299) Incremental Cost AVP code */ int INCREMENTAL_COST = 2062; /** * Ro/Rf (3GPP TS 32.299) Interface Id AVP code */ int INTERFACE_ID = 2003; /** * Ro/Rf (3GPP TS 32.299) Interface Port AVP code */ int INTERFACE_PORT = 2004; /** * Ro/Rf (3GPP TS 32.299) Interface Text AVP code */ int INTERFACE_TEXT = 2005; /** * Ro/Rf (3GPP TS 32.299) Interface Type AVP code */ int INTERFACE_TYPE = 2006; /** * Ro/Rf (3GPP TS 32.299) Inter Operator Identifier AVP code */ int INTER_OPERATOR_IDENTIFIER = 838; /** * Ro/Rf (3GPP TS 32.299) LCS Client Dialed By MS AVP code */ int LCS_CLIENT_DIALED_BY_MS = 1233; /** * Ro/Rf (3GPP TS 32.299) LCS Client External ID AVP code */ int LCS_CLIENT_EXTERNAL_ID = 1234; /** * Ro/Rf (3GPP TS 32.299) LCS Client Id AVP code */ int LCS_CLIENT_ID = 1232; /** * Ro/Rf (3GPP TS 32.299) LCS Client Type AVP code */ int LCS_CLIENT_TYPE = 1241; /** * Ro/Rf (3GPP TS 32.299) LCS Data Coding Scheme AVP code */ int LCS_DATA_CODING_SCHEME = 1236; /** * Ro/Rf (3GPP TS 32.299) LCS Format Indicator AVP code */ int LCS_FORMAT_INDICATOR = 1237; /** * Ro/Rf (3GPP TS 32.299) LCS Information AVP code */ int LCS_INFORMATION = 878; /** * Ro/Rf (3GPP TS 32.299) LCS Name String AVP code */ int LCS_NAME_STRING = 1238; /** * Ro/Rf (3GPP TS 32.299) LCS Requestor Id AVP code */ int LCS_REQUESTOR_ID = 1239; /** * Ro/Rf (3GPP TS 32.299) LCS Requestor Id String AVP code */ int LCS_REQUESTOR_ID_STRING = 1240; /** * Ro/Rf (3GPP TS 32.299) Local Sequence Number AVP code */ int LOCAL_SEQUENCE_NUMBER = 2063; /** * Ro/Rf (3GPP TS 32.299) Location Estimate AVP code */ int LOCATION_ESTIMATE = 1242; /** * Ro/Rf (3GPP TS 32.299) Location Estimate Type AVP code */ int LOCATION_ESTIMATE_TYPE = 1243; /** * Ro/Rf (3GPP TS 32.299) Location Type AVP code */ int LOCATION_TYPE = 1244; /** * Ro/Rf (3GPP TS 32.299) Max Requested Bandwidth DL AVP code */ int MAX_REQUESTED_BANDWIDTH_DL = 515; /** * Ro/Rf (3GPP TS 32.299) Max Requested Bandwidth UL AVP code */ int MAX_REQUESTED_BANDWIDTH_UL = 516; /** * Ro/Rf (3GPP TS 32.299) MBMS 2G 3G Indicator AVP code */ int MBMS_2G_3G_INDICATOR = 907; /** * Ro/Rf (3GPP TS 32.299) MBMS Information AVP code */ int MBMS_INFORMATION = 880; /** * Ro/Rf (3GPP TS 32.299) MBMS Service Area AVP code */ int MBMS_SERVICE_AREA = 903; /** * Ro/Rf (3GPP TS 32.299) MBMS Service Type AVP code */ int MBMS_SERVICE_TYPE = 906; /** * Ro/Rf (3GPP TS 32.299) MBMS Session Identity AVP code */ int MBMS_SESSION_IDENTITY = 908; /** * Ro/Rf (3GPP TS 32.299) MBMS User Service Type AVP code */ int MBMS_USER_SERVICE_TYPE = 1225; /** * Ro/Rf (3GPP TS 32.299) Media Initiator Flag AVP code */ int MEDIA_INITIATOR_FLAG = 882; /** * Ro/Rf (3GPP TS 32.299) Media Initiator Party AVP code */ int MEDIA_INITIATOR_PARTY = 1288; /** * Ro/Rf (3GPP TS 32.299) Message Body AVP code */ int MESSAGE_BODY = 889; /** * Ro/Rf (3GPP TS 32.299) Message Class AVP code */ int MESSAGE_CLASS = 1213; /** * Ro/Rf (3GPP TS 32.299) Message ID AVP code */ int MESSAGE_ID = 1210; /** * Ro/Rf (3GPP TS 32.299) Message Size AVP code */ int MESSAGE_SIZE = 1212; /** * Ro/Rf (3GPP TS 32.299) Message Type AVP code */ int MESSAGE_TYPE = 1211; /** * Ro/Rf (3GPP TS 32.299) MMBox Storage Requested AVP code */ int MMBOX_STORAGE_REQUESTED = 1248; /** * Ro/Rf (3GPP TS 32.299) MM Content Type AVP code */ int MM_CONTENT_TYPE = 1203; /** * Ro/Rf (3GPP TS 32.299) MMS Information AVP code */ int MMS_INFORMATION = 877; /** * Ro/Rf (3GPP TS 32.299) MMTel Information AVP code */ int MMTEL_INFORMATION = 2030; /** * Ro/Rf (3GPP TS 32.299) MSISDN AVP code */ int MSISDN = 701; /** * Ro/Rf (3GPP TS 32.299) Next Tariff AVP code */ int NEXT_TARIFF = 2057; /** * Ro/Rf (3GPP TS 32.299) Node Functionality AVP code */ int NODE_FUNCTIONALITY = 862; /** * Ro/Rf (3GPP TS 32.299) Node Id AVP code */ int NODE_ID = 2064; /** * Ro/Rf (3GPP TS 32.299) Number Of Diversions AVP code */ int NUMBER_OF_DIVERSIONS = 2034; /** * Ro/Rf (3GPP TS 32.299) Number Of Messages Sent AVP code */ int NUMBER_OF_MESSAGES_SENT = 2019; /** * Ro/Rf (3GPP TS 32.299) Number Of Messages Successfully Exploded AVP code */ int NUMBER_OF_MESSAGES_SUCCESSFULLY_EXPLODED = 2111; /** * Ro/Rf (3GPP TS 32.299) Number Of Messages Successfully Sent AVP code */ int NUMBER_OF_MESSAGES_SUCCESSFULLY_SENT = 2112; /** * Ro/Rf (3GPP TS 32.299) Number Of Participants AVP code */ int NUMBER_OF_PARTICIPANTS = 885; /** * Ro/Rf (3GPP TS 32.299) Number Of Received Talk Bursts AVP code */ int NUMBER_OF_RECEIVED_TALK_BURSTS = 1282; /** * Ro/Rf (3GPP TS 32.299) Number Of Talk Bursts AVP code */ int NUMBER_OF_TALK_BURSTS = 1283; /** * Ro/Rf (3GPP TS 32.299) Number Portability Routing Information AVP code */ int NUMBER_PORTABILITY_ROUTING_INFORMATION = 2024; /** * Ro/Rf (3GPP TS 32.299) Offline Charging AVP code */ int OFFLINE_CHARGING = 1278; /** * Ro/Rf (3GPP TS 32.299) Online Charging Flag AVP code */ int ONLINE_CHARGING_FLAG = 2303; /** * Ro/Rf (3GPP TS 32.299) Originating IOI AVP code */ int ORIGINATING_IOI = 839; /** * Ro/Rf (3GPP TS 32.299) Originator SCCP Address AVP code */ int ORIGINATOR_SCCP_ADDRESS = 2008; /** * Ro/Rf (3GPP TS 32.299) Originator AVP code */ int ORIGINATOR = 864; /** * Ro/Rf (3GPP TS 32.299) Originator Address AVP code */ int ORIGINATOR_ADDRESS = 886; /** * Ro/Rf (3GPP TS 32.299) Originator Received Address AVP code */ int ORIGINATOR_RECEIVED_ADDRESS = 2027; /** * Ro/Rf (3GPP TS 32.299) Originator Interface AVP code */ int ORIGINATOR_INTERFACE = 2009; /** * Ro/Rf (3GPP TS 32.299) Outgoing Trunk Group Id AVP code */ int OUTGOING_TRUNK_GROUP_ID = 853; /** * Ro/Rf (3GPP TS 32.299) Participant Access Priority AVP code */ int PARTICIPANT_ACCESS_PRIORITY = 1259; /** * Ro/Rf (3GPP TS 32.299) Participant Action Type AVP code */ int PARTICIPANT_ACTION_TYPE = 2049; /** * Ro/Rf (3GPP TS 32.299) Participant Group AVP code */ int PARTICIPANT_GROUP = 1260; /** * Ro/Rf (3GPP TS 32.299) Participants Involved AVP code */ int PARTICIPANTS_INVOLVED = 887; /** * Ro/Rf (3GPP TS 32.299) PDG Address AVP code */ int PDG_ADDRESS = 895; /** * Ro/Rf (3GPP TS 32.299) PDG Charging Id AVP code */ int PDG_CHARGING_ID = 896; /** * Ro/Rf (3GPP TS 32.299) PDN Connection ID AVP code */ int PDN_CONNECTION_ID = 2050; /** * Ro/Rf (3GPP TS 32.299) PDP Address AVP code */ int PDP_ADDRESS = 1227; /** * Ro/Rf (3GPP TS 32.299) PDP Context Type AVP code */ int PDP_CONTEXT_TYPE = 1247; /** * Ro/Rf (3GPP TS 32.299) PoC Change Condition AVP code */ int POC_CHANGE_CONDITION = 1261; /** * Ro/Rf (3GPP TS 32.299) PoC Change Time AVP code */ int POC_CHANGE_TIME = 1262; /** * Ro/Rf (3GPP TS 32.299) PoC Controlling Address AVP code */ int POC_CONTROLLING_ADDRESS = 858; /** * Ro/Rf (3GPP TS 32.299) PoC Event Type AVP code */ int POC_EVENT_TYPE = 2025; /** * Ro/Rf (3GPP TS 32.299) PoC Group Name AVP code */ int POC_GROUP_NAME = 859; /** * Ro/Rf (3GPP TS 32.299) PoC Information AVP code */ int POC_INFORMATION = 879; /** * Ro/Rf (3GPP TS 32.299) PoC Server Role AVP code */ int POC_SERVER_ROLE = 883; /** * Ro/Rf (3GPP TS 32.299) PoC Session Id AVP code */ int POC_SESSION_ID = 1229; /** * Ro/Rf (3GPP TS 32.299) PoC Session Initiation type AVP code */ int POC_SESSION_INITIATION_TYPE = 1277; /** * Ro/Rf (3GPP TS 32.299) PoC Session Type AVP code */ int POC_SESSION_TYPE = 884; /** * Ro/Rf (3GPP TS 32.299) PoC User Role AVP code */ int POC_USER_ROLE = 1252; /** * Ro/Rf (3GPP TS 32.299) PoC User Role IDs AVP code */ int POC_USER_ROLE_IDS = 1253; /** * Ro/Rf (3GPP TS 32.299) PoC User Role info Units AVP code */ int POC_USER_ROLE_INFO_UNITS = 1254; /** * Ro/Rf (3GPP TS 32.299) Positioning Data AVP code */ int POSITIONING_DATA = 1245; /** * Ro/Rf (3GPP TS 32.299) Priority AVP code */ int PRIORITY = 1209; /** * Ro/Rf (3GPP TS 32.299) Priority Level AVP code */ int PRIORITY_LEVEL = 1046; /** * Ro/Rf (3GPP TS 32.299) PS Append Free Format Data AVP code */ int PS_APPEND_FREE_FORMAT_DATA = 867; /** * Ro/Rf (3GPP TS 32.299) PS Free Format Data AVP code */ int PS_FREE_FORMAT_DATA = 866; /** * Ro/Rf (3GPP TS 32.299) PS Furnish Charging Information AVP code */ int PS_FURNISH_CHARGING_INFORMATION = 865; /** * Ro/Rf (3GPP TS 32.299) PS Information AVP code */ int PS_INFORMATION = 874; /** * Ro/Rf (3GPP TS 32.299) QoS Information AVP code */ int QOS_INFORMATION = 1016; /** * Ro/Rf (3GPP TS 32.299) QoS Class Identifier AVP code */ int QOS_CLASS_IDENTIFIER = 1028; /** * Ro/Rf (3GPP TS 32.299) Quota Consumption Time AVP code */ int QUOTA_CONSUMPTION_TIME = 881; /** * Ro/Rf (3GPP TS 32.299) Quota Holding Time AVP code */ int QUOTA_HOLDING_TIME = 871; /** * Ro/Rf (3GPP TS 32.299) RAI AVP code */ int RAI = 909; /** * Ro/Rf (3GPP TS 32.299) Rate Element AVP code */ int RATE_ELEMENT = 2058; /** * Ro/Rf (3GPP TS 32.299) Read Reply Report Requested AVP code */ int READ_REPLY_REPORT_REQUESTED = 1222; /** * Ro/Rf (3GPP TS 32.299) Received Talk Burst Time AVP code */ int RECEIVED_TALK_BURST_TIME = 1284; /** * Ro/Rf (3GPP TS 32.299) Received Talk Burst Volume AVP code */ int RECEIVED_TALK_BURST_VOLUME = 1285; /** * Ro/Rf (3GPP TS 32.299) Recipient Address AVP code */ int RECIPIENT_ADDRESS = 1201; /** * Ro/Rf (3GPP TS 32.299) Recipient Info AVP code */ int RECIPIENT_INFO = 2026; /** * Ro/Rf (3GPP TS 32.299) Recipient Received Address AVP code */ int RECIPIENT_RECEIVED_ADDRESS = 2028; /** * Ro/Rf (3GPP TS 32.299) Recipient SCCP Address AVP code */ int RECIPIENT_SCCP_ADDRESS = 2010; /** * Ro/Rf (3GPP TS 32.299) Refund Information AVP code */ int REFUND_INFORMATION = 2022; /** * Ro/Rf (3GPP TS 32.299) Remaining Balance AVP code */ int REMAINING_BALANCE = 2021; /** * Ro/Rf (3GPP TS 32.299) Reply Applic ID AVP code */ int REPLY_APPLIC_ID = 1223; /** * Ro/Rf (3GPP TS 32.299) Reply Path Requested AVP code */ int REPLY_PATH_REQUESTED = 2011; /** * Ro/Rf (3GPP TS 32.299) Reporting Reason AVP code */ int REPORTING_REASON = 872; /** * Ro/Rf (3GPP TS 32.299) Requested Party Address AVP code */ int REQUESTED_PARTY_ADDRESS = 1251; /** * Ro/Rf (3GPP TS 32.299) Required MBMS Bearer Capabilities AVP code */ int REQUIRED_MBMS_BEARER_CAPABILITIES = 901; /** * Ro/Rf (3GPP TS 32.299) Role of Node AVP code */ int ROLE_OF_NODE = 829; /** * Ro/Rf (3GPP TS 32.299) Scale Factor AVP code */ int SCALE_FACTOR = 2059; /** * Ro/Rf (3GPP TS 32.299) SDP Answer Timestamp AVP code */ int SDP_ANSWER_TIMESTAMP = 1275; /** * Ro/Rf (3GPP TS 32.299) SDP Media Component AVP code */ int SDP_MEDIA_COMPONENT = 843; /** * Ro/Rf (3GPP TS 32.299) SDP Media Description AVP code */ int SDP_MEDIA_DESCRIPTION = 845; /** * Ro/Rf (3GPP TS 32.299) SDP Media Name AVP code */ int SDP_MEDIA_NAME = 844; /** * Ro/Rf (3GPP TS 32.299) SDP Offer Timestamp AVP code */ int SDP_OFFER_TIMESTAMP = 1274; /** * Ro/Rf (3GPP TS 32.299) SDP Session Description AVP code */ int SDP_SESSION_DESCRIPTION = 842; /** * Ro/Rf (3GPP TS 32.299) SDP TimeStamps AVP code */ int SDP_TIMESTAMPS = 1273; /** * Ro/Rf (3GPP TS 32.299) SDP Type AVP code */ int SDP_TYPE = 2036; /** * Ro/Rf (3GPP TS 32.299) Served Party IP Address AVP code */ int SERVED_PARTY_IP_ADDRESS = 848; /** * Ro/Rf (3GPP TS 32.299) Service Data Container AVP code */ int SERVICE_DATA_CONTAINER = 2040; /** * Ro/Rf (3GPP TS 32.299) Service Generic Information AVP code */ int SERVICE_GENERIC_INFORMATION = 1256; /** * Ro/Rf (3GPP TS 32.299) Service Id AVP code */ int SERVICE_IDENTIFIER = 855; /** * Ro/Rf (3GPP TS 32.299) Service Information AVP code */ int SERVICE_INFORMATION = 873; /** * Ro/Rf (3GPP TS 32.299) Service Mode AVP code */ int SERVICE_MODE = 2032; /** * Ro/Rf (3GPP TS 32.299) Service Specific Data AVP code */ int SERVICE_SPECIFIC_DATA = 863; /** * Ro/Rf (3GPP TS 32.299) Service Specific Info AVP code */ int SERVICE_SPECIFIC_INFO = 1249; /** * Ro/Rf (3GPP TS 32.299) Service Specific Type AVP code */ int SERVICE_SPECIFIC_TYPE = 1257; /** * Ro/Rf (3GPP TS 32.299) Serving Node Type AVP code */ int SERVING_NODE_TYPE = 2047; /** * Ro/Rf (3GPP TS 32.299) Service Type AVP code */ int SERVICE_TYPE = 2031; /** * Ro/Rf (3GPP TS 32.299) SGSN Address AVP code */ int SGSN_ADDRESS = 1228; /** * Ro/Rf (3GPP TS 32.299) SGW Change AVP code */ int SGW_CHANGE = 2064; /** * Ro/Rf (3GPP TS 32.299) SIP Method AVP code */ int SIP_METHOD = 824; /** * Ro/Rf (3GPP TS 32.299) SIP Request Timestamp Fraction AVP code */ int SIP_REQUEST_TIMESTAMP_FRACTION = 2301; /** * Ro/Rf (3GPP TS 32.299) SIP Request Timestamp AVP code */ int SIP_REQUEST_TIMESTAMP = 834; /** * Ro/Rf (3GPP TS 32.299) SIP Response Timestamp Fraction AVP code */ int SIP_RESPONSE_TIMESTAMP_FRACTION = 2302; /** * Ro/Rf (3GPP TS 32.299) SIP Response Timestamp AVP code */ int SIP_RESPONSE_TIMESTAMP = 835; /** * Ro/Rf (3GPP TS 32.299) SM Discharge Time AVP code */ int SM_DISCHARGE_TIME = 2012; /** * Ro/Rf (3GPP TS 32.299) SM Message Type AVP code */ int SM_MESSAGE_TYPE = 2007; /** * Ro/Rf (3GPP TS 32.299) SM Protocol ID AVP code */ int SM_PROTOCOL_ID = 2013; /** * Ro/Rf (3GPP TS 32.299) SMSC Address AVP code */ int SMSC_ADDRESS = 2017; /** * Ro/Rf (3GPP TS 32.299) SMS Information AVP code */ int SMS_INFORMATION = 2000; /** * Ro/Rf (3GPP TS 32.299) SMS Node AVP code */ int SMS_NODE = 2016; /** * Ro/Rf (3GPP TS 32.299) SM Service Type AVP code */ int SM_SERVICE_TYPE = 2029; /** * Ro/Rf (3GPP TS 32.299) SM Status AVP code */ int SM_STATUS = 2014; /** * Ro/Rf (3GPP TS 32.299) SM User Data Header AVP code */ int SM_USER_DATA_HEADER = 2015; /** * Ro/Rf (3GPP TS 32.299) Start Time AVP code */ int START_TIME = 2041; /** * Ro/Rf (3GPP TS 32.299) Stop Time AVP code */ int STOP_TIME = 2042; /** * Ro/Rf (3GPP TS 32.299) Submission Time AVP code */ int SUBMISSION_TIME = 1202; /** * Ro/Rf (3GPP TS 32.299) Subscriber Role AVP code */ int SUBSCRIBER_ROLE = 2033; /** * Ro/Rf (3GPP TS 32.299) Supplementary Service AVP code */ int SUPPLEMENTARY_SERVICE = 2048; /** * Ro/Rf (3GPP TS 32.299) Talk Burst Exchange AVP code */ int TALK_BURST_EXCHANGE = 1255; /** * Ro/Rf (3GPP TS 32.299) Talk Burst Time AVP code */ int TALK_BURST_TIME = 1286; /** * Ro/Rf (3GPP TS 32.299) Talk Burst Volume AVP code */ int TALK_BURST_VOLUME = 1287; /** * Ro/Rf (3GPP TS 32.299) Tariff Information AVP code */ int TARIFF_INFORMATION = 2060; /** * Ro/Rf/S13 (3GPP TS 32.299) Terminal Information AVP code */ int TERMINAL_INFORMATION = 1401; /** * Ro/Rf (3GPP TS 32.299) Terminating IOI AVP code */ int TERMINATING_IOI = 840; /** * Ro/Rf (3GPP TS 32.299) Time First Usage AVP code */ int TIME_FIRST_USAGE = 2043; /** * Ro/Rf (3GPP TS 32.299) Time Last Usage AVP code */ int TIME_LAST_USAGE = 2044; /** * Ro/Rf (3GPP TS 32.299) Time Quota Mechanism AVP code */ int TIME_QUOTA_MECHANISM = 1270; /** * Ro/Rf (3GPP TS 32.299) Time Quota Threshold AVP code */ int TIME_QUOTA_THRESHOLD = 868; /** * Ro/Rf (3GPP TS 32.299) Time Quota Type AVP code */ int TIME_QUOTA_TYPE = 1271; /** * Ro/Rf (3GPP TS 32.299) Time Stamps AVP code */ int TIME_STAMPS = 833; /** * Ro/Rf (3GPP TS 32.299) Time Usage AVP code */ int TIME_USAGE = 2045; /** * Ro/Rf (3GPP TS 32.299) TMGI AVP code */ int TMGI = 900; /** * Ro/Rf (3GPP TS 32.299) Token Text AVP code */ int TOKEN_TEXT = 1215; /** * Ro/Rf (3GPP TS 32.299) Total Number Of Messages Exploded AVP code */ int TOTAL_NUMBER_OF_MESSAGES_EXPLODED = 2113; /** * Ro/Rf (3GPP TS 32.299) Total Number Of Messages Sent AVP code */ int TOTAL_NUMBER_OF_MESSAGES_SENT = 2114; /** * Ro/Rf (3GPP TS 32.299) Traffic Data Volumes AVP code */ int TRAFFIC_DATA_VOLUMES = 2046; /** * Ro/Rf (3GPP TS 32.299) Trigger AVP code */ int TRIGGER = 1264; /** * Ro/Rf (3GPP TS 32.299) Trigger Type AVP code */ int TRIGGER_TYPE = 870; /** * Ro/Rf (3GPP TS 32.299) Trunk Group Id AVP code */ int TRUNK_GROUP_ID = 851; /** * Ro/Rf (3GPP TS 32.299) Type Number AVP code */ int TYPE_NUMBER = 1204; /** * Ro/Rf (3GPP TS 32.299) Unit Cost AVP code */ int UNIT_COST = 2061; /** * Ro/Rf (3GPP TS 32.299) Unit Quota Threshold AVP code */ int UNIT_QUOTA_THRESHOLD = 1226; /** * Ro/Rf (3GPP TS 32.299) User Data AVP code */ int USER_DATA_RORF = 606; /** * Ro/Rf (3GPP TS 32.299) User Participating Type AVP code */ int USER_PARTICIPATING_TYPE = 1279; /** * Ro/Rf (3GPP TS 32.299) User Session Id AVP code */ int USER_SESSION_ID = 830; /** * Ro/Rf (3GPP TS 32.299) VAS Id AVP code */ int VAS_ID = 1102; /** * Ro/Rf (3GPP TS 32.299) VASP Id AVP code */ int VASP_ID = 1101; /** * Ro/Rf (3GPP TS 32.299) Volume Quota Threshold AVP code */ int VOLUME_QUOTA_THRESHOLD = 869; /** * Ro/Rf (3GPP TS 32.299) WAG Address AVP code */ int WAG_ADDRESS = 890; /** * Ro/Rf (3GPP TS 32.299) WAG PLMN Id AVP code */ int WAG_PLMN_ID = 891; /** * Ro/Rf (3GPP TS 32.299) WLAN Information AVP code */ int WLAN_INFORMATION = 875; /** * Ro/Rf (3GPP TS 32.299) WLAN Radio Container AVP code */ int WLAN_RADIO_CONTAINER = 892; /** * Ro/Rf (3GPP TS 32.299) WLAN Session Id AVP code */ int WLAN_SESSION_ID = 1246; /** * Ro/Rf (3GPP TS 32.299) WLAN Technology AVP code */ int WLAN_TECHNOLOGY = 893; /** * Ro/Rf (3GPP TS 32.299) WLAN UE Local IPAddress AVP code */ int WLAN_UE_LOCAL_IPADDRESS = 894; // S13/S13' Interfaces AVPs /** * S13/S13' (3GPP TS 29.272) 3GPP IMEI AVP code */ int TGPP_IMEI = 1402; /** * S13/S13' (3GPP TS 29.272) Software Version AVP code */ int SOFTWARE_VERSION = 1403; /** * S13/S13' (3GPP TS 29.272) Equipment-Status AVP code */ int EQUIPMENT_STATUS = 1445; /** * S13/S13' (3GPP TS 29.272) 3GPP2 MEID AVP code */ int TGPP2_MEID = 1471; /********************************************************/ /*** SLh interface (GMLC - HSS) AVPs (3GPP TS 29.173) ***/ /********************************************************/ /** * SLh (3GPP TS 29.173) LMSI AVP code */ int LMSI = 2400; /** * SLh (3GPP TS 29.173) Serving-Node AVP code */ int SERVING_NODE = 2401; /** * SLh (3GPP TS 29.173) MME-Name AVP code */ int MME_NAME = 2402; /** * SLh (3GPP TS 29.173) MCS-Number AVP code */ int MSC_NUMBER = 2403; /** * SLh (3GPP TS 29.173) LCS-Capabilities-Sets AVP code */ int LCS_CAPABILITIES_SETS = 2404; /** * SLh (3GPP TS 29.173) GMLC-Address AVP code */ int GMLC_ADDRESS = 2405; /** * SLh (3GPP TS 29.173) Additional-Serving-Node AVP code */ int ADDITIONAL_SERVING_NODE = 2406; /** * SLh (3GPP TS 29.173) PPR-Address AVP code */ int PPR_ADDRESS = 2407; /** * SLh (3GPP TS 29.173) MME-Realm AVP code */ int MME_REALM = 2408; /** * SLh (3GPP TS 29.173) SGSN-Name AVP code */ int SGSN_NAME = 2409; /** * SLh (3GPP TS 29.173) SGSN-Realm AVP code */ int SGSN_REALM = 2410; /** * SLh (3GPP TS 29.173) RIA-Flags AVP code */ int RIA_FLAGS = 2411; /** * SLh (3GPP TS 29.173) SGSN-Number AVP code (reused from 3GPP TS 29.272, MME - SGSN interface) */ int SGSN_NUMBER = 1489; /** * SLh (3GPP TS 29.173) GMLC-Number AVP code (reused from 3GPP TS 29.272, MME - SGSN interface) */ int GMLC_NUMBER = 1474; /** * SLh (3GPP TS 29.173) 3GPP-AAA-Server-Name AVP code (reused from 3GPP TS 29.273, 3GPP AAA EPS interface) */ int TGPP_AAA_SERVER_NAME = 318; // SLh re-used Diameter AVPs: // MSISDN 3GPP TS 29.329; // SGSN-Number 3GPP TS 29.272; // Supported-Features 3GPP TS 29.229; // Feature-List-ID 3GPP TS 29.229; // Feature-List 3GPP TS 29.229; // GMLC-Number 3GPP TS 29.272; // 3GPP-AAA-Server-Name 3GPP TS 29.273 /********************************************************/ /*** SLg interface (GMLC - MME) AVPs (3GPP TS 29.172) ***/ /*** Diameter ELP Application (EPC LCS Protocol) ***/ /********************************************************/ /** * SLg (3GPP TS 29.172) SLg-Location-Type AVP code */ int SLG_LOCATION_TYPE = 2500; /** * SLg (3GPP TS 29.172) LCS-EPS-Client-Name AVP code */ int LCS_EPS_CLIENT_NAME = 2501; /** * SLg (3GPP TS 29.172) LCS_Requestor_Name AVP code */ int LCS_REQUESTOR_NAME = 2502; /** * SLg (3GPP TS 29.172) LCS-Priority AVP code */ int LCS_PRIORITY = 2503; /** * SLg (3GPP TS 29.172) LCS-QoS AVP code */ int LCS_QOS = 2504; /** * SLg (3GPP TS 29.172) Horizontal-Accuracy AVP code */ int HORIZONTAL_ACCURACY = 2505; /** * SLg (3GPP TS 29.172) Vertical-Accuracy AVP code */ int VERTICAL_ACCURACY = 2506; /** * SLg (3GPP TS 29.172) Vertical-Requested AVP code */ int VERTICAL_REQUESTED = 2507; /** * SLg (3GPP TS 29.172) Velocity-Requested AVP code */ int VELOCITY_REQUESTED = 2508; /** * SLg (3GPP TS 29.172) Response-Time AVP code */ int RESPONSE_TIME = 2509; /** * SLg (3GPP TS 29.172) LCS-Supported-GAD-Shapes AVP code */ int LCS_SUPPORTED_GAD_SHAPES = 2510; /** * SLg (3GPP TS 29.172) LCS-Codeword AVP code */ int LCS_CODEWORD = 2511; /** * SLg (3GPP TS 29.172) LCS-Privacy-Check AVP code */ int LCS_PRIVACY_CHECK = 2512; /** * SLg (3GPP TS 29.172) Accuracy-Fulfilment-Indicator AVP code */ int ACCURACY_FULFILMENT_INDICATOR = 2513; /** * SLg (3GPP TS 29.172) Age-Of-Location-Estimate AVP code */ int AGE_OF_LOCATION_ESTIMATE = 2514; /** * SLg (3GPP TS 29.172) Velocity-Estimate 2515 AVP code */ int VELOCITY_ESTIMATE = 2515; /** * SLg (3GPP TS 29.172) EUTRAN-Positioning-Data AVP code */ int EUTRAN_POSITIONING_DATA = 2516; /** * SLg (3GPP TS 29.172) ECGI AVP code */ int ECGI = 2517; /** * SLg (3GPP TS 29.172) Location_Event AVP code */ int LOCATION_EVENT = 2518; /** * SLg (3GPP TS 29.172) Pseudonym-Indicator */ int PSEUDONYM_INDICATOR = 2519; /** * SLg (3GPP TS 29.172) LCS-Service-Type-ID AVP Code */ int LCS_SERVICE_TYPE_ID = 2520; /** * SLg (3GPP TS 29.172) LCS-Privacy-Check-Non-Session AVP Code */ int LCS_PRIVACY_CHECK_NON_SESSION = 2521; /** * SLg (3GPP TS 29.172) LCS-Privacy-Check-Session AVP Code */ int LCS_PRIVACY_CHECK_SESSION = 2522; /** * SLg (3GPP TS 29.172) LCS-QoS-Class AVP Code */ int LCS_QOS_CLASS = 2523; /** * SLg (3GPP TS 29.172) GERAN-Positioning-Info AVP Code */ int GERAN_POSITIONING_INFO = 2524; /** * SLg (3GPP TS 29.172) GERAN-Positioning-Data AVP Code */ int GERAN_POSITIONING_DATA = 2525; /** * SLg (3GPP TS 29.172) GERAN-GANSS-Positioning-Data AVP Code */ int GERAN_GANSS_POSITIONING_DATA = 2526; /** * SLg (3GPP TS 29.172) UTRAN-Positioning-Info AVP Code */ int UTRAN_POSITIONING_INFO = 2527; /** * SLg (3GPP TS 29.172) UTRAN-Positioning-Data AVP Code */ int UTRAN_POSITIONING_DATA = 2528; /** * SLg (3GPP TS 29.172) UTRAN-GANSS-Positioning-Data AVP Code */ int UTRAN_GANSS_POSITIONING_DATA = 2529; /** * SLg (3GPP TS 29.172) LRR-Flags AVP Code */ int LRR_FLAGS = 2530; /** * SLg (3GPP TS 29.172) LCS-Reference-Number AVP Code */ int LCS_REFERENCE_NUMBER = 2531; /** * SLg (3GPP TS 29.172) Deferred-Location-Type AVP Code */ int DEFERRED_LOCATION_TYPE = 2532; /** * SLg (3GPP TS 29.172) Area-Event-Info AVP Code */ int AREA_EVENT_INFO = 2533; /** * SLg (3GPP TS 29.172) Area-Definition AVP Code */ int AREA_DEFINITION = 2534; /** * SLg (3GPP TS 29.172) Area AVP Code */ int AREA = 2535; /** * SLg (3GPP TS 29.172) Area-Type AVP Code */ int AREA_TYPE = 2536; /** * SLg (3GPP TS 29.172) Area-Identification AVP Code */ int AREA_IDENTIFICATION = 2537; /** * SLg (3GPP TS 29.172) Occurrence-Info AVP Code */ int OCCURRENCE_INFO = 2538; /** * SLg (3GPP TS 29.172) Interval-Time AVP Code */ int INTERVAL_TIME = 2539; /** * SLg (3GPP TS 29.172) Periodic-LDR-Information AVP Code */ int PERIODIC_LDR_INFORMATION = 2540; /** * SLg (3GPP TS 29.172) Reporting-Amount AVP Code */ int REPORTING_AMOUNT = 2541; /** * SLg (3GPP TS 29.172) Reporting-Interval AVP Code */ int REPORTING_INTERVAL = 2542; /** * SLg (3GPP TS 29.172) Reporting-PLMN-List AVP Code */ int REPORTING_PLMN_LIST = 2543; /** * SLg (3GPP TS 29.172) PLMN-ID-List AVP Code */ int PLMN_ID_LIST = 2544; /** * SLg (3GPP TS 29.172) PLR-Flags AVP Code */ int PLR_FLAGS = 2545; /** * SLg (3GPP TS 29.172) PLA-Flags AVP Code */ int PLA_FLAGS = 2546; /** * SLg (3GPP TS 29.172) Deferred-MT-LR-Data AVP Code */ int DEFERRED_MT_LR_DATA = 2547; /** * SLg (3GPP TS 29.172) Termination-Cause AVP Code; */ int TERMINATION_CAUSE_LCS = 2548; /** * SLg (3GPP TS 29.172) LRA-Flags AVP Code */ int LRA_FLAGS = 2549; /** * SLg (3GPP TS 29.172) Periodic-Location-Support-Indicator AVP Code */ int PERIODIC_LOCATION_SUPPORT_INDICATOR = 2550; /** * SLg (3GPP TS 29.172) */ int PRIORITIZED_LIST_INDICATOR = 2551; /** * SLg (3GPP TS 29.172)ESMLC-Cell-Info AVP Code */ int ESMLC_CELL_INFO = 2552; /** * SLg (3GPP TS 29.172) Cell-Portion-ID AVP Code */ int CELL_PORTION_ID = 2553; /** * SLg (3GPP TS 29.172) 1xRTT-RCID AVP Code */ int ONEXRTT_RCID = 2554; /** * SLg (3GPP TS 29.172) Civic-Address AVP Code */ int CIVIC_ADDRESS = 2556; /** * SLg (3GPP TS 29.172) Barometric-Pressure AVP Code */ int BAROMETRIC_PRESSURE = 2557; /** * SLg (3GPP TS 29.172) UTRAN-Additional-Positioning-Data AVP Code */ int UTRAN_ADDITIONAL_POSITIONING_DATA = 2558; /** * SLg (3GPP TS 29.172) Motion-Event-Info */ int MOTION_EVENT_INFO = 2559; /** * SLg (3GPP TS 29.172) Linear-Distance */ int LINEAR_DISTANCE = 2560; /** * SLg (3GPP TS 29.172) Maximum-Interval */ int MAXIMUM_INTERVAL = 2561; /** * SLg (3GPP TS 29.172) Sampling-Interval */ int SAMPLING_INTERVAL = 2562; /** * SLg (3GPP TS 29.172) Reporting-Duration */ int REPORTING_DURATION = 2563; /** * SLg (3GPP TS 29.172) Reporting-Location-Requirements */ int REPORTING_LOCATION_REQUIREMENTS = 2564; /** * SLg (3GPP TS 29.172) Additional-Area */ int ADDITIONAL_AREA = 2565; /** * SLg (3GPP TS 29.172) Service-Selection AVP Code (reused from 3GPP TS 29.272 & IETF RFC 5778) */ int SERVICE_SELECTION = 493; /** * SLg (3GPP TS 29.172) Cell-Global-Identity AVP Code (reused from 3GPP TS 29.272) */ int CELL_GLOBAL_IDENTITY = 1604; /** * SLg (3GPP TS 29.172) Visited-PLMN-Id AVP Code (reused from 3GPP TS 29.272) */ int VISITED_PLMN_ID = 1407; /** * SLg (3GPP TS 29.172) Service-Area-Identity AVP Code (reused from 3GPP TS 29.272) */ int SERVICE_AREA_IDENTITY = 1607; // Diameter ELP Application (SLg) reused AVPs: // LCS-Format-Indicator 1237 3GPP TS 32.299; // LCS-Name-String 1238 3GPP TS 2.299; // LCS-Client-Type 1241 3GPP TS 32.299 // LCS-Requestor-Id-String 1240 3GPP TS 32.299; // Location-Estimate 1242 3GPP TS 32.299; // IMEI 1402 3GPP TS 29.272; // MSISDN 701 3GPP TS 29.329; // Service-Selection 493 3GPP TS 29.272, IETF RFC 5778 // User-Name 1 IETF RFC 3588; // Supported-Features 628 3GPP TS 29.229; // Feature-List-ID 629 3GPP TS 29.229; // Feature-List 630 3GPP TS 29.229; // Serving-Node 2401 3GPP TS 29.173; // Cell-Global-Identity 1604 3GPP TS 29.272; // Service-Area-Identity 1607 3GPP TS 29.272; // GMLC-Address 2405 3GPP TS 29.173; // Visited-PLMN-Id 1407 3GPP TS 29.272 /** * @return the AVP code. */ int getCode(); /** * @return true if Vendor-id is present in Avp header */ boolean isVendorId(); /** * @return true if flag M is set 1 */ boolean isMandatory(); /** * @return true if flag E is set 1 */ boolean isEncrypted(); /** * @return Vendor-Id if it present (-1 if it not avalible) */ long getVendorId(); /** * @return data as byte array (Raw format) * * @throws AvpDataException if data has incorrect format */ byte[] getRaw() throws AvpDataException; /** * @return data as an String (Use AS-ASCI code page) * * @throws AvpDataException if data has incorrect format */ byte[] getOctetString() throws AvpDataException; /** * @return data as an integer * * @throws AvpDataException if data has incorrect format */ int getInteger32() throws AvpDataException; /** * @return data as an unsigned long * * @throws AvpDataException if data has incorrect format */ long getInteger64() throws AvpDataException; /** * @return data as an unsigned integer * * @throws AvpDataException if data has incorrect format */ long getUnsigned32() throws AvpDataException; /** * @return data as an long * * @throws AvpDataException if data has incorrect format */ long getUnsigned64() throws AvpDataException; /** * @return data as an float * * @throws AvpDataException if data has incorrect format */ float getFloat32() throws AvpDataException; /** * @return data as an double * * @throws AvpDataException if data has incorrect format */ double getFloat64() throws AvpDataException; /** * @return data as an Diameter Address (Inet4Address or Inet6Address) * * @throws AvpDataException if data has incorrect format */ InetAddress getAddress() throws AvpDataException; /** * @return data as an Diameter Time (millisecond is truncated) * * @throws AvpDataException if data has incorrect format */ Date getTime() throws AvpDataException; /** * @return data as an String (Use UTF-8 code page) * * @throws AvpDataException if data has incorrect format */ String getUTF8String() throws AvpDataException; /** * @return data as an String (Use AS-ASCI code page) * * @throws AvpDataException if data has incorrect format */ String getDiameterIdentity() throws AvpDataException; /** * @return data as an Diamter URI * * @throws AvpDataException if data has incorrect format */ URI getDiameterURI() throws AvpDataException; /** * @return data as an AVP group. * * @throws AvpDataException if data has incorrect format */ AvpSet getGrouped() throws AvpDataException; byte[] getRawData(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/AvpDataException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * The AvpDataException signals invalid operations on Avp data. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AvpDataException extends Exception { private static final long serialVersionUID = -5898449417016355792L; protected Avp avp; /** * Default constructor */ public AvpDataException(Avp avp) { super(); this.avp = avp; } /** * Constructor with reason string * * @param message reason string */ public AvpDataException(String message, Avp avp) { super(message); this.avp = avp; } /** * Constructor with reason string and parent exception * * @param message message reason string * @param cause parent exception */ public AvpDataException(String message, Throwable cause, Avp avp) { super(message, cause); this.avp = avp; } /** * Constructor with parent exception * * @param cause parent exception */ public AvpDataException(Throwable cause, Avp avp) { super(cause); this.avp = avp; } /** * Default constructor */ public AvpDataException() { super(); } /** * Constructor with reason string * * @param message reason string */ public AvpDataException(String message) { super(message); } /** * Constructor with reason string and parent exception * * @param message message reason string * @param cause parent exception */ public AvpDataException(String message, Throwable cause) { super(message, cause); } /** * Constructor with parent exception * * @param cause parent exception */ public AvpDataException(Throwable cause) { super(cause); } public Avp getAvp() { return avp; } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/AvpSet.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.io.Serializable; import java.net.InetAddress; import java.util.Date; /** * A set of data representing a message avp set. AvpSet is simple container of avps allows direct access to Avp by Avp * code or index of Avp. The AvpSet interface provides add/rem methods for appending new Avp and remove Avp from AvpSet. * Wrapper interface allows adapt message to any driver vendor specific interface Serializable interface allows use this * class in SLEE Event objects * * @author erick.svenson@yahoo.com * @author Grzegorz Figiel [ProIDS] * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface AvpSet extends Iterable, Serializable, Wrapper { /** * get AVP by code * * @param avpCode code of Avp * * @return Avp instance */ Avp getAvp(int avpCode); /** * get AVP by position * * @param index position of Avp * * @return Avp instance */ Avp getAvpByIndex(int index); /** * get AVP by code * * @param avpCode code of Avp * @param vendorId vendor of Avp * * @return Avp instance */ Avp getAvp(int avpCode, long vendorId); /** * get AVP by code * * @param avpCode code of Avp * * @return array Avp instance */ AvpSet getAvps(int avpCode); /** * get AVP by code * * @param avpCode code of Avp * @param vendorId vendor of Avp * * @return array Avp instance */ AvpSet getAvps(int avpCode, long vendorId); /** * Get position of the first instance of the AVP * * @param avpCode code of the Avp * * @return index (position) of the first occurrence of the Avp. -1 in case Avp is not found */ int getAvpIndex(int avpCode); /** * Get position of the first instance of the AVP * * @param avpCode code of the Avp * @param vendorId vendorId of the Avp * * @return index (position) of the first occurrence of the Avp. -1 in case Avp is not found */ int getAvpIndex(int avpCode, long vendorId); /** * Remove AVPs with avpCode * * @param avpCode code of Avp * * @return array of removed Avps instance */ AvpSet removeAvp(int avpCode); /** * Remove AVPs with avpCode * * @param avpCode code of Avp * @param vendorId code of Vendor * * @return array of removed Avps instance */ AvpSet removeAvp(int avpCode, long vendorId); /** * Remove Avp by Avp index * * @param index Avp position * * @return Avp instance */ Avp removeAvpByIndex(int index); /** * Return count of top Avps * * @return size of top Avps */ int size(); /** * Return array of avp * * @return array of avp */ Avp[] asArray(); /** * Append avp array as value * * @param value avp array */ void addAvp(Avp... value); /** * Append array of avps * * @param value avp array from AvpSet container */ void addAvp(AvpSet value); /** * Append byte[] AVP * * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp addAvp(int avpCode, byte[] value); /** * Append byte[] AVP * * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, byte[] value, boolean mFlag, boolean pFlag); /** * Append byte[] AVP * * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, byte[] value, long vendorId, boolean mFlag, boolean pFlag); /** * Append int AVP * * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp addAvp(int avpCode, int value); /** * Append int AVP * * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, int value, boolean mFlag, boolean pFlag); /** * Append int AVP * * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, int value, long vendorId, boolean mFlag, boolean pFlag); /** * Append long(integer64) AVP * * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp addAvp(int avpCode, long value); /** * Append long(integer64) AVP * * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, long value, boolean mFlag, boolean pFlag); /** * Append long(integer64) AVP * * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, long value, long vendorId, boolean mFlag, boolean pFlag); /** * Append long(integer64) AVP * * @param avpCode code of Avp * @param value Avp data * @param asUnsignedInt32 true if value is unsigned integer 32 type * * @return Avp instance */ Avp addAvp(int avpCode, long value, boolean asUnsignedInt32); /** * Append long(integer64) AVP * * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * @param asUnsignedInt32 true if value is unsigned integer 32 type * * @return Avp instance */ Avp addAvp(int avpCode, long value, boolean mFlag, boolean pFlag, boolean asUnsignedInt32); /** * Append long(integer64) AVP * * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * @param asUnsignedInt32 true if value is unsigned integer 32 type * * @return Avp instance */ Avp addAvp(int avpCode, long value, long vendorId, boolean mFlag, boolean pFlag, boolean asUnsignedInt32); /** * Append float AVP * * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp addAvp(int avpCode, float value); /** * Append float AVP * * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, float value, boolean mFlag, boolean pFlag); /** * Append float AVP * * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, float value, long vendorId, boolean mFlag, boolean pFlag); /** * Append double(float64) AVP * * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp addAvp(int avpCode, double value); /** * Append double(float64) AVP * * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, double value, boolean mFlag, boolean pFlag); /** * Append double(float64) AVP * * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, double value, long vendorId, boolean mFlag, boolean pFlag); /** * Append String(UTF-8 or Octet) AVP * * @param avpCode code of Avp * @param value Avp data * @param asOctetString true if it octet string * * @return Avp instance */ Avp addAvp(int avpCode, String value, boolean asOctetString); /** * Append String(UTF-8 or Octet) AVP * * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * @param asOctetString true if it octet string * * @return Avp instance */ Avp addAvp(int avpCode, String value, boolean mFlag, boolean pFlag, boolean asOctetString); /** * Append String(UTF-8 or Octet) AVP * * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * @param asOctetString true if it octet string * * @return Avp instance */ Avp addAvp(int avpCode, String value, long vendorId, boolean mFlag, boolean pFlag, boolean asOctetString); /** * Append URI AVP * * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp addAvp(int avpCode, URI value); /** * Append URI AVP * * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, URI value, boolean mFlag, boolean pFlag); /** * Append URI AVP * * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, URI value, long vendorId, boolean mFlag, boolean pFlag); /** * Append Address AVP * * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp addAvp(int avpCode, InetAddress value); /** * Append Address AVP * * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, InetAddress value, boolean mFlag, boolean pFlag); /** * Append Address AVP * * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, InetAddress value, long vendorId, boolean mFlag, boolean pFlag); /** * Append Diameter Time AVP * * @param avpCode code of Avp * @param date value * * @return Avp instance */ Avp addAvp(int avpCode, Date date); /** * Append Diameter Time AVP * * @param avpCode code of Avp * @param date value * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, Date date, boolean mFlag, boolean pFlag); /** * Append Diameter Time AVP * * @param avpCode code of Avp * @param date value * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp addAvp(int avpCode, Date date, long vendorId, boolean mFlag, boolean pFlag); /** * Append Grouped AVP * * @param avpCode code of Avp * * @return AvpSet instance */ AvpSet addGroupedAvp(int avpCode); /** * Append Grouped AVP * * @param avpCode code of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return AvpSet instance */ AvpSet addGroupedAvp(int avpCode, boolean mFlag, boolean pFlag); /** * Append Grouped AVP * * @param avpCode code of Avp * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return AvpSet instance */ AvpSet addGroupedAvp(int avpCode, long vendorId, boolean mFlag, boolean pFlag); /** * Insert AvpSet * * @param index index of inserted avp * @param value avp array */ void insertAvp(int index, Avp... value); /** * Insert AvpSet * * @param index index of inserted avp * @param value avp array from AvpSet container */ void insertAvp(int index, AvpSet value); /** * Insert byte[] AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp insertAvp(int index, int avpCode, byte[] value); /** * Insert byte[] AVP * * @param avpCode code of Avp * @param index index of inserted avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, byte[] value, boolean mFlag, boolean pFlag); /** * Insert byte[] AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, byte[] value, long vendorId, boolean mFlag, boolean pFlag); /** * Insert int AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp insertAvp(int index, int avpCode, int value); /** * Insert int AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, int value, boolean mFlag, boolean pFlag); /** * Insert int AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, int value, long vendorId, boolean mFlag, boolean pFlag); /** * Insert long(integer64) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp insertAvp(int index, int avpCode, long value); /** * Insert long(integer64) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, long value, boolean mFlag, boolean pFlag); /** * Insert long(integer64) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, long value, long vendorId, boolean mFlag, boolean pFlag); /** * Insert long(integer64) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param asUnsignedInt32 true if value is unisignet integer 32 type * * @return Avp instance */ Avp insertAvp(int index, int avpCode, long value, boolean asUnsignedInt32); /** * Insert long(integer64) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * @param asUnsignedInt32 true if value is unisignet integer 32 type * * @return Avp instance */ Avp insertAvp(int index, int avpCode, long value, boolean mFlag, boolean pFlag, boolean asUnsignedInt32); /** * Insert long(integer64) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * @param asUnsignedInt32 true if value is unisignet integer 32 type * * @return Avp instance */ Avp insertAvp(int index, int avpCode, long value, long vendorId, boolean mFlag, boolean pFlag, boolean asUnsignedInt32); /** * Insert float AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp insertAvp(int index, int avpCode, float value); /** * Insert float AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, float value, boolean mFlag, boolean pFlag); /** * Insert float AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, float value, long vendorId, boolean mFlag, boolean pFlag); /** * Insert double(float64) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp insertAvp(int index, int avpCode, double value); /** * Insert double(float64) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, double value, boolean mFlag, boolean pFlag); /** * Insert double(float64) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, double value, long vendorId, boolean mFlag, boolean pFlag); /** * Insert String(UTF-8 or Octet) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param asOctetString true if it octet string * * @return Avp instance */ Avp insertAvp(int index, int avpCode, String value, boolean asOctetString); /** * Insert String(UTF-8 or Octet) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * @param asOctetString true if it octet string * * @return Avp instance */ Avp insertAvp(int index, int avpCode, String value, boolean mFlag, boolean pFlag, boolean asOctetString); /** * Insert String(UTF-8 or Octet) AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * @param asOctetString true if it octet string * * @return Avp instance */ Avp insertAvp(int index, int avpCode, String value, long vendorId, boolean mFlag, boolean pFlag, boolean asOctetString); /** * Insert URI AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp insertAvp(int index, int avpCode, URI value); /** * Insert URI AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, URI value, boolean mFlag, boolean pFlag); /** * Insert URI AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, URI value, long vendorId, boolean mFlag, boolean pFlag); /** * Insert Address AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * * @return Avp instance */ Avp insertAvp(int index, int avpCode, InetAddress value); /** * Insert Address AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, InetAddress value, boolean mFlag, boolean pFlag); /** * Insert Address AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param value Avp data * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, InetAddress value, long vendorId, boolean mFlag, boolean pFlag); /** * Insert Diameter Time AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param date value * * @return Avp instance */ Avp insertAvp(int index, int avpCode, Date date); /** * Insert Diameter Time AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param date value * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, Date date, boolean mFlag, boolean pFlag); /** * Insert Diameter Time AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param date value * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return Avp instance */ Avp insertAvp(int index, int avpCode, Date date, long vendorId, boolean mFlag, boolean pFlag); /** * Insert Grouped AVP * * @param index index of inserted avp * @param avpCode code of Avp * * @return AvpSet instance */ AvpSet insertGroupedAvp(int index, int avpCode); /** * Insert Grouped AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return AvpSet instance */ AvpSet insertGroupedAvp(int index, int avpCode, boolean mFlag, boolean pFlag); /** * Insert Grouped AVP * * @param index index of inserted avp * @param avpCode code of Avp * @param vendorId vendor of Avp * @param mFlag true set M flag/false clear M flag in header Avp * @param pFlag true set P flag/false clear P flag in header Avp * * @return AvpSet instance */ AvpSet insertGroupedAvp(int index, int avpCode, long vendorId, boolean mFlag, boolean pFlag); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/BaseSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * The session delivery objects are responsible for delivering all incoming Message to a specific session. It determines * the Diameter Session object that the message belongs to by querying the message's session id AVP. The delivery object * searches the local session database for a matching session. If no matching session is found, the delivery object will * lookup a matching session factory object that has an application id matching the application id of the message. If * there is a registered session factory, then the delivery object will ask the factory to create a new session and * delivery the message to the newly created session. If non of these lookup's are successful, the session delivery * object will silently discard the message. Wrapper interface allows adapt message to any driver vendor specific * interface Serializable interface allows use this class in SLEE Event objects * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface BaseSession { /** * Returns the time when this session was created (milliseconds) Start point of time January 1, 1970 GMT. * * @return long specifying when this session was created */ long getCreationTime(); /** * Returns the last time an event occurred on this session (milliseconds) Start point of time January 1, 1970 GMT. * * @return long specifying when last time an event occurred on this session */ long getLastAccessedTime(); /** * Return true if session is not released * * @return true if session is not released */ boolean isValid(); /** * Release all resources append to session */ void release(); /** * Indicates if this is an App Session or a raw/base session * * @return */ boolean isAppSession(); /** * Indicates if the session is replicable * * @return */ boolean isReplicable(); /** * @return session-id as String (Session-Id AVP) */ String getSessionId(); String IDLE_SESSION_TIMER_NAME = "IDLE_SESSION_TIMER"; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Configuration.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * Stack properties for working. This interface equals IMemento interface from Eclispe (pattern Memento). It interface * hideWay of a storage of stack properties (XML file ant etc) * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Configuration { /** * Returns the Byte point value of the given key. * * @param key the key * @param defaultValue the Default Value * @return the value, or defValue if the key was not found or was found but was not a Byte point number */ byte getByteValue(int key, byte defaultValue); /** * Returns the Integer point value of the given key. * * @param key the key * @param defaultValue the Default Value * @return the value, or defaultValue if the key was not found or was found but was not a Integer point * number */ int getIntValue(int key, int defaultValue); /** * Returns the long point value of the given key. * * @param key the key * @param defaultValue the Default Value * @return the value, or defaultValue if the key was not found or was found but was not a long point * number */ long getLongValue(int key, long defaultValue); /** * Returns the double point value of the given key. * * @param key the key * @param defaultValue the Default Value * @return the value, or defaultValue if the key was not found or was found but was not a double point * number */ double getDoubleValue(int key, double defaultValue); /** * Returns the byte[] point value of the given key. * * @param key the key * @param defaultValue the Default Value * @return the value, or defaultValue if the key was not found or was found but was not a byte[] point * number */ byte[] getByteArrayValue(int key, byte[] defaultValue); /** * Returns the boolean point value of the given key. * * @param key the key * @param defaultValue the Default Value * @return the value, or defaultValue if the key was not found or was found but was not a boolean point * number */ boolean getBooleanValue(int key, boolean defaultValue); /** * Returns the String point value of the given key. * * @param key the key * @param defaultValue the Default Value * @return the value, or defaultValue if the key was not found or was found but was not a String point * number */ String getStringValue(int key, String defaultValue); /** * @param key key of attribute * @return true if value of parameter is not null */ boolean isAttributeExist(int key); /** * Returns all children with the given type id. * * @param key the type id * @return an array of children with the given type */ Configuration[] getChildren(int key); /** * Returns the Object piont value for the given key * * @param key the key * @return the value */ Object getValue(int key); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ConfigurationListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * The listener interface for receiving runtime configuration changes events. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ConfigurationListener { /** * Invoked when an changes is occurs. * * @param key index of changed element * @param newValue new value * * @return true if new value is applied */ boolean elementChanged(int key, Object newValue); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/DisconnectCause.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * Interface defining disconnect cause codes * * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface DisconnectCause { /** * A scheduled reboot is imminent. */ int REBOOTING = 0; /** * The peer's internal resources are constrained, and it has determined that the transport connection needs to be * closed. */ int BUSY = 1; /** * The peer has determined that it does not see a need for the transport connection to exist, since it does not * expect any messages to be exchanged in the near future. */ int DO_NOT_WANT_TO_TALK_TO_YOU = 2; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/EventListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * Common event listener * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface EventListener { /** * Notifies this Listener that stack has received diameter answer message. For network requests - answer parameter * is null * * @param request the request message * @param answer the answer on application request */ void receivedSuccessMessage(R request, A answer); /** * Notifies this Listener that the request has timeout. * * @param request the request has timeout */ void timeoutExpired(R request); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/IllegalDiameterStateException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * Signals that a method has been invoked at an illegal or inappropriate time. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public class IllegalDiameterStateException extends Exception { private static final long serialVersionUID = 1L; public IllegalDiameterStateException() { } public IllegalDiameterStateException(String message) { super(message); } public IllegalDiameterStateException(String message, Throwable cause) { super(message, cause); } public IllegalDiameterStateException(Throwable cause) { super(cause); } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/InternalException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * An exception that provides information on a stack error or other errors. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public class InternalException extends Exception { private static final long serialVersionUID = 1L; /** * Default constructor */ public InternalException() { super(); } /** * Constructor with reason string * * @param message reason string */ public InternalException(String message) { super(message); } /** * Constructor with reason string and parent exception * * @param message message reason string * @param cause parent exception */ public InternalException(String message, Throwable cause) { super(message, cause); } /** * Constructor with parent exception * * @param cause parent exception */ public InternalException(Throwable cause) { super(cause); } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/LocalAction.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This Enum class defines commCode of realm local actions * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ public enum LocalAction { LOCAL, RELAY, PROXY, REDIRECT } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Message.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.io.Serializable; import java.util.List; /** * A Diameter message is either a request from a client to a server, or a response from a server to a client. Both * Request and Answer messages use the basic format of RFC 3588 Wrapper interface allows adapt message to any driver * vendor specific interface The message must support adaptable operation to Answer and Request interfaces Serializable * interface allows use this class in SLEE Event objects * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Message extends Wrapper, Serializable { /** * The Abort-Session-Request message code */ int ABORT_SESSION_REQUEST = 274; /** * The Abort-Session-Answer message code */ int ABORT_SESSION_ANSWER = 274; /** * The Accounting-Request message code */ int ACCOUNTING_REQUEST = 271; /** * The Accounting-Answer message code */ int ACCOUNTING_ANSWER = 271; /** * The Capabilities-Exchange-Request message code */ int CAPABILITIES_EXCHANGE_REQUEST = 257; /** * The Capabilities-Exchange-Answer message code */ int CAPABILITIES_EXCHANGE_ANSWER = 257; /** * The Device-Watchdog-Request message code */ int DEVICE_WATCHDOG_REQUEST = 280; /** * The Device-Watchdog-Answer message code */ int DEVICE_WATCHDOG_ANSWER = 280; /** * The Disconnect-Peer-Request message code */ int DISCONNECT_PEER_REQUEST = 282; /** * The Disconnect-Peer-Answer message code */ int DISCONNECT_PEER_ANSWER = 282; /** * The Re-Auth-Request message code */ int RE_AUTH_REQUEST = 258; /** * The Re-Auth-Answer message code */ int RE_AUTH_ANSWER = 258; /** * The Session-Termination-Request message code */ int SESSION_TERMINATION_REQUEST = 275; /** * The Session-Termination-Answer message code */ int SESSION_TERMINATION_ANSWER = 275; /** * @return version of message (version filed in header) */ byte getVersion(); /** * @return value of R bit from header of message */ boolean isRequest(); /** * Set 1 or 0 to R bit field of header * * @param value true == 1 or false = 0 */ void setRequest(boolean value); /** * @return value of P bit from header of message */ boolean isProxiable(); /** * Set 1 or 0 to P bit field of header * * @param value true == 1 or false = 0 */ void setProxiable(boolean value); /** * @return value of E bit from header of message */ boolean isError(); /** * Set 1 or 0 to E bit field of header * * @param value true == 1 or false = 0 */ void setError(boolean value); /** * @return value of T bit from header of message */ boolean isReTransmitted(); /** * Set 1 or 0 to T bit field of header * * @param value true == 1 or false = 0 */ void setReTransmitted(boolean value); /** * @return command code from header of message */ int getCommandCode(); /** * Return message Session Id avp Value (null if avp not set) * * @return session id avp of message */ String getSessionId(); /** * Return ApplicationId value from message header * * @return ApplicationId value from message header */ long getApplicationId(); /** * Returns ordered list of Application-Id avps (Auth-Application-Id, Acc-Appplication-Id and * Vendor-Specific-Application-Id avps) from message * * @return list of Application-Id avps */ List getApplicationIdAvps(); /** * The Hop-by-Hop Identifier is an unsigned 32-bit integer field (in network byte order) and aids in matching * requests and replies. The sender MUST ensure that the Hop-by-Hop identifier in a request is unique on a given * connection at any given time, and MAY attempt to ensure that the number is unique across reboots. * * @return hop by hop identifier from header of message */ long getHopByHopIdentifier(); /** * The End-to-End Identifier is an unsigned 32-bit integer field (in network byte order) and is used to detect * duplicate messages. Upon reboot implementations MAY set the high order 12 bits to contain the low order 12 bits * of current time, and the low order 20 bits to a random value. Senders of request messages MUST insert a unique * identifier on each message. * * @return end to end identifier from header of message */ long getEndToEndIdentifier(); /** * @return Set of message Avps */ AvpSet getAvps(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/MetaData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This interface is implemented by sack vendors to let users know the local properties of a Diameter Stack * implementation and current instance. * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface MetaData extends Wrapper { /** * @return Retrieves the stack's major version number. */ int getMajorVersion(); /** * @return Retrieves the stack's minor version number. */ int getMinorVersion(); /** * @return stack type */ StackType getStackType(); /** * @return information about local instance of peer */ Peer getLocalPeer(); /** * Return configuration parameters * * @return configuration */ Configuration getConfiguration(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Mode.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This enumerated class define type of stack start condition * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ public enum Mode { ANY_PEER, ALL_PEERS } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/MutableConfiguration.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This interface is the extended version of the interface configuration and allows to receive of a notification about * reconfigurations * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface MutableConfiguration extends Configuration { /** * Set byte value to configuration * * @param key key of value * @param value byte value */ void setByteValue(int key, byte value); /** * Set int value to configuration * * @param key key of value * @param value int value */ void setIntValue(int key, int value); /** * Set long value to configuration * * @param key key of value * @param value long value */ void setLongValue(int key, long value); /** * Set double value to configuration * * @param key key of value * @param value double value */ void setDoubleValue(int key, double value); /** * Set byte array value to configuration * * @param key key of value * @param value byte array value */ void setByteArrayValue(int key, byte[] value); /** * Set boolean value to configuration * * @param key key of value * @param value boolean value */ void setBooleanValue(int key, boolean value); /** * Set string value to configuration * * @param key key of value * @param value string value */ void setStringValue(int key, String value); /** * Set children to configuration * * @param key key of children * @param value children value */ void setChildren(int key, Configuration... value); /** * Remove defined key * * @param key array keys of removed entry */ void removeValue(int... key); /** * Add change configuration listener * * @param listener instance of listener * @param keys array of observed propertie's keys if keys.length == 0 then observed all properties of * configuration node */ void addChangeListener(ConfigurationListener listener, int... keys); /** * Remove change configuration listener * * @param listener instance of listener * @param keys array of removed listener's keys */ void removeChangeListener(ConfigurationListener listener, int... keys); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/MutablePeerTable.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This interface extends PeerTable interface and append some operation for controls peer and realm table * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface MutablePeerTable extends PeerTable { /** * Return peer statistics * * @param peerHost host of peer * * @return peer statistics */ Statistic getStatistic(String peerHost); /** * Append peer table listener * * @param listener listener instance */ void setPeerTableListener(PeerTableListener listener); /** * Add new peer to peer table * * @param peer URI of peer (host, port and other connection information) for example: * aaa://host.example.com:6666;transport=tcp;protocol=diameter * @param realmName name of realm * @param connecting attempt connect * * @return peer instance */ Peer addPeer(URI peer, String realmName, boolean connecting); /** * Remove peer from peer table * * @param peerHost host of peer * * @return removed peer instance */ Peer removePeer(String peerHost); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Network.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This interface introduces a capability to work with a network. You can get instance of this interface over stack * instance: * * if (stack.isWrapperFor(Network.class)) { Network netWork = stack.unwrap(Network.class); ..... } * * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Network extends Wrapper { /** * Return local peer network statistics * * @return network statistics */ Statistic getStatistic(); /** * Register listener for processing network requests * * @param applicationId application Id * @param listener request listener * * @throws ApplicationAlreadyUseException if listener with predefined appId already append to network */ void addNetworkReqListener(NetworkReqListener listener, ApplicationId... applicationId) throws ApplicationAlreadyUseException; /** * Register listener for processing network requests * * @param selector application selector * @param listener request listener */ void addNetworkReqListener(NetworkReqListener listener, Selector... selector); /** * Remove request listener * * @param applicationId application id of listener */ void removeNetworkReqListener(ApplicationId... applicationId); /** * Remove request listener * * @param selector selector of application */ void removeNetworkReqListener(Selector... selector); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/NetworkReqListener.java ================================================ /* * JBoss, Home of Professional Open Source * Copyright 2006, 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.jdiameter.api; /** * The NetworkReqListener interface is used to process network requests. This listener can be attach to session or to * network class instances * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface NetworkReqListener { /** * This method use for process new network requests. * * @param request request message * * @return answer immediate answer message. Method may return null and an Answer will be sent later on */ Answer processRequest(Request request); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/OverloadException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * An exception that provides information on a stack has application request overload. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public class OverloadException extends Exception { private static final long serialVersionUID = 1L; double lowThreshold, highThreshold, value; /** * Default constructor */ public OverloadException() { super(); } /** * Constructor with overload data * * @param lowThreshold low threshold overload value * @param highThreshold high threshold overload value * @param value current overload value */ public OverloadException(double lowThreshold, double highThreshold, double value) { this.lowThreshold = lowThreshold; this.highThreshold = highThreshold; this.value = value; } /** * Constructor with reason string * * @param message reason string */ public OverloadException(String message) { super(message); } /** * Constructor with reason string and parent exception * * @param message message reason string * @param cause parent exception */ public OverloadException(String message, Throwable cause) { super(message, cause); } /** * Constructor with parent exception * * @param cause parent exception */ public OverloadException(Throwable cause) { super(cause); } /** * @return current low threshold overload value */ public double getLowThreshold() { return lowThreshold; } /** * @return current high threshold overload value */ public double getHighThreshold() { return highThreshold; } /** * @return current overload value */ public double getValue() { return value; } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/OverloadListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This class allows processed stack overloaded notification * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface OverloadListener { /** * Notifies this OverloadListener that the stack has overload. * * @param peer listening peer * @param value value of overload */ void overloadDetected(URI peer, double value); /** * Notifies this OverloadListener that the stack has overload cased * * @param peer listening peer */ void overloadCeased(URI peer); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/OverloadManager.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This interface allows to control the stack at overload moment * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface OverloadManager { /** * Notify stack that parent application has overload * * @param id Overloaded application id (null for stack owner) * @param type type of overload (CPU, Memory..) * @param value value of overload */ void parentAppOverloadDetected(ApplicationId id, int type, double value); /** * Notifies stack that parent application has overload cased * * @param id Overloaded application id (null for stack owner) * @param type type of overload (CPU, Memory..) */ void parentAppOverloadCeased(ApplicationId id, int type); /** * Append overload listener * * @param listener overload listener instance * @param lowThreshold low value of overload threshold (for example 0.8 - 1.0 is overload Range) * @param highThreshold high value of overload threshold (for example 0.8 - 1.0 is overload Range) * @param qIndex overload element index */ void addOverloadListener(OverloadListener listener, double lowThreshold, double highThreshold, int qIndex); /** * Remove overload listener * * @param listener overload listener instance * @param qIndex overload element index */ void removeOverloadListener(OverloadListener listener, int qIndex); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Peer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.io.IOException; import java.net.InetAddress; import java.util.Set; /** * Peer contains everything that is worth knowing about a peer and define some operation for working with this peer. * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Peer { /** * Establishes a connection towards a remote peer. * * @throws IllegalDiameterStateException */ void connect() throws InternalException, IOException, IllegalDiameterStateException; /** * Close the connection to the peer. * * @throws IllegalDiameterStateException */ void disconnect(int disconnectCause) throws InternalException, IllegalDiameterStateException; /** * All implementations must support PeerState interface as argument * * @return state of peer */ E getState(Class enumc); /** * @return URI of peer */ URI getUri(); /** * @return array of peer ip addresses */ InetAddress[] getIPAddresses(); /** * @return Realm name of peer */ String getRealmName(); /** * @return vendor id of peer stack implementation */ long getVendorId(); /** * @return product name of peer stack implementation */ String getProductName(); /** * @return firmware version of peer stack implementation */ long getFirmware(); /** * @return set of common Application-id of peer; */ Set getCommonApplications(); /** * Append peer state change listener to the peer manager * * @param listener listener instance */ void addPeerStateListener(PeerStateListener listener); /** * Remove peer state change listener from the peer manager * * @param listener listener instance */ void removePeerStateListener(PeerStateListener listener); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/PeerState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This enumerated class define Peer states. More information you can read on document "Authentication, Authorization * and Accounting (AAA) Transport Profile" * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ public enum PeerState { OKAY, SUSPECT, DOWN, REOPEN, INITIAL } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/PeerStateListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This interface is used to inform about changes in the state for a given peer. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface PeerStateListener { /** * A change of state has occurred for a peer. * * @param oldState old state of peer * @param newState new state of peer */ void stateChanged(PeerState oldState, PeerState newState); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/PeerTable.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.util.List; /** * PeerManager is Diameter Stack PCB(RFC 3588) realization. Wrapper interface allows adapt message to any driver vendor * specific interface. List of wrapper classes: - Server API : Network, MutablePeerTable * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface PeerTable extends Wrapper { /** * Return peer by host name * * @param peerHost host name * * @return peer */ Peer getPeer(String peerHost); /** * Return no mutable list of peers * * @return List of current stack known peers */ List getPeerTable(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/PeerTableListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This interface is used to inform about changes in the peer table. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface PeerTableListener { /** * This method notified about adding a new peer to peer table * * @param peer peer instance */ void peerAccepted(Peer peer); /** * This method notified about removing a peer from peer table * * @param peer peer instance */ void peerRemoved(Peer peer); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/RawSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * This interface append to base interface specific methods for creating and send raw diameter messages * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface RawSession extends BaseSession, Wrapper { /** * Returns a new message object with the specified command code, applicationId and predefined avps. * * @param commandCode code of message * @param applicationId applicationId of destination application * @param avp array of avps * * @return new message object */ Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp); /** * Returns a new message object with the predefined Command-code, ApplicationId, HopByHopIdentifier, * EndToEndIdentifier This method allow created message from storage or created specific message. * * @param commandCode code of message * @param applicationId applicationId of destination application * @param hopByHopIdentifier hop by hop identifier of message * @param endToEndIdentifier end to end identifier of message * @param avp array of avps * * @return new message object */ Message createMessage(int commandCode, ApplicationId applicationId, long hopByHopIdentifier, long endToEndIdentifier, Avp... avp); /** * Returns a new message object with the copy of parent message header * * @param message origination message * @param copyAvps if true all avps will be copy to new message * * @return Returns a new message object with the copy of parent message header */ Message createMessage(Message message, boolean copyAvps); /** * Sends and wait response message with default timeout * * @param message request/answer diameter message * @param listener event listener * * @throws org.jdiameter.api.InternalException The InternalException signals that internal error is * occurred. * @throws org.jdiameter.api.IllegalDiameterStateException The IllegalStateException signals that session has * incorrect state (invalid). * @throws org.jdiameter.api.RouteException The NoRouteException signals that no route exist for a * given realm. * @throws org.jdiameter.api.OverloadException The OverloadException signals that destination host is * overloaded. */ void send(Message message, EventListener listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Sends and wait response message with defined timeout * * @param message request/answer diameter message * @param listener event listener * @param timeOut value of timeout * @param timeUnit type of timeOut value * * @throws org.jdiameter.api.InternalException The InternalException signals that internal error is * occurred. * @throws org.jdiameter.api.IllegalDiameterStateException The IllegalStateException signals that session has * incorrect state (invalid). * @throws org.jdiameter.api.RouteException The NoRouteException signals that no route exist for a * given realm. * @throws org.jdiameter.api.OverloadException The OverloadException signals that destination host is * overloaded. */ void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Sends and wait response message with default timeout * * @param message request/answer diameter message * * @return InFuture result of an asynchronous operation * * @throws org.jdiameter.api.InternalException The InternalException signals that internal error is * occurred. * @throws org.jdiameter.api.IllegalDiameterStateException The IllegalStateException signals that session has * incorrect state (invalid). * @throws org.jdiameter.api.RouteException The NoRouteException signals that no route exist for a * given realm. * @throws org.jdiameter.api.OverloadException The OverloadException signals that destination host is * overloaded. */ Future send(Message message) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Sends and wait response message with defined timeout * * @param message request/answer diameter message * @param timeOut value of timeout * @param timeUnit type of timeOut value * * @return InFuture result of an asynchronous operation * * @throws org.jdiameter.api.InternalException The InternalException signals that internal error is * occurred. * @throws org.jdiameter.api.IllegalDiameterStateException The IllegalStateException signals that session has * incorrect state (invalid). * @throws org.jdiameter.api.RouteException The NoRouteException signals that no route exist for a * given realm. * @throws org.jdiameter.api.OverloadException The OverloadException signals that destination host is * overloaded. */ Future send(Message message, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Realm.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * Base Realm interface. * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface Realm { /** * Return name of this realm * * @return name */ String getName(); /** * Return applicationId associated with this realm * * @return applicationId */ ApplicationId getApplicationId(); /** * Return realm local action for this realm * * @return realm local action */ LocalAction getLocalAction(); /** * Return true if this realm is dynamic updated * * @return true if this realm is dynamic updated */ boolean isDynamic(); /** * Return expiration time for this realm in milisec * * @return expiration time */ long getExpirationTime(); /** * Returns true if realm is local. Local means that it is defined as local(not action) realm for this peer. * * @return */ boolean isLocal(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/RealmTable.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This interface introduces a capability to work with a network. You can get instance of this interface over stack * instance: * * if (stack.isWrapperFor(RealmTable.class)) { RealmTable realmTabke = stack.unwrap(RealmTable.class); ..... } * * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface RealmTable extends Wrapper { /** * Return different network statistics * * @param realmName realmName * * @return network statistics */ Statistic getStatistic(String realmName); /** * Add new realm to realm table * * @param realmName name of realm * @param applicationId application id of realm * @param action action of realm * @param agentConfiguration resource for configuration of action dependent agent, may be null. * @param dynamic commCode of realm * @param expTime expiration time of realm * @param extraConf - additional configuration which may be used by implementation * * @return instance of created realm * * @throws InternalException - when realm definition under pKey and sKey exist */ Realm addRealm(String realmName, ApplicationId applicationId, LocalAction action, String agentConfiguration, boolean dynamic, long expTime, String[] hosts) throws InternalException; /** * Checks if there is such realm entry. * * @param realmName * * @return */ boolean realmExists(String realmName); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Request.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * A Diameter Request is a request from a client to a server (or server to client - network request). * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface Request extends Message { /** * @return true if it is network request */ boolean isNetworkRequest(); /** * Creates an answer for this request with the specified result code. Header and system AVPs from request are copied * to answer. * * @param resultCode result code of answer * * @return answer object instance */ Answer createAnswer(long resultCode); /** * Creates an answer for this request with the specified experimental result code. Header and system AVPs from * request are copied to answer. * * @param vendorId vendorId * @param experimentalResultCode experimental result code of answer * * @return answer object instance */ Answer createAnswer(long vendorId, long experementalResultCode); /** * Creates answer for this request. Header and system AVPs from request are copied to answer. * * @return */ Answer createAnswer(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ResultCode.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This interface describe basic result codes * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ResultCode { /** * This informational error is returned by a Diameter server to inform the access device that the authentication * mechanism being used requires multiple round trips, and a subsequent request needs to be issued in order for * access to be granted. */ int MULTI_ROUND_AUTH = 1001; /** * The Request was successfully completed. */ int SUCCESS = 2001; /** * When returned, the request was successfully completed, but additional processing is required by the application * in order to provide service to the user. */ int LIMITED_SUCCESS = 2002; /** * The Request contained a Command-Code that the receiver did not recognize or support. This MUST be used when a * Diameter node receives an experimental command that it does not understand. */ int COMMAND_UNSUPPORTED = 3001; /** * This error is given when Diameter can not deliver the message to the destination, either because no host within * the realm supporting the required application was available to process the request, or because Destination-Host * AVP was given without the associated Destination-Realm AVP */ int UNABLE_TO_DELIVER = 3002; /** * The intended realm of the request is not recognized. */ int REALM_NOT_SERVED = 3003; /** * When returned, a Diameter node SHOULD attempt to send the message to an alternate peer. This error MUST only be * used when a specific server is requested, and it cannot provide the requested service. */ int TOO_BUSY = 3004; /** * An agent detected a loop while trying to get the message to the intended recipient. The message MAY be sent to * an alternate peer, if one is available, but the peer reporting the error has identified a configuration problem. */ int LOOP_DETECTED = 3005; /** * A redirect agent has determined that the request could not be satisfied locally and the initiator of the request * should direct the request directly to the server, whose contact information has been added to the response. When * set, the Redirect-Host AVP MUST be present. */ int REDIRECT_INDICATION = 3006; /** * A request was sent for an application that is not supported. */ int APPLICATION_UNSUPPORTED = 3007; /** * A request was received whose bits in the Diameter header were either set to an invalid combination, or to a value * that is inconsistent with the command code's definition. */ int INVALID_HDR_BITS = 3008; /** * A request was received that included an AVP whose flag bits are set to an unrecognized value, or that is * inconsistent with the AVP's definition. */ int INVALID_AVP_BITS = 3009; /** * A CER was received from an unknown peer. */ int UNKNOWN_PEER = 3010; /** * The authentication process for the user failed, most likely due to an invalid password used by the user. Further * attempts MUST only be tried after prompting the user for a new password. */ int AUTHENTICATION_REJECTED = 4001; /** * A Diameter node received the accounting request but was unable to commit it to stable storage due to a temporary * lack of space. */ int OUT_OF_SPACE = 4002; /** * The peer has determined that it has lost the election process and has therefore disconnected the transport * connection. */ int ELECTION_LOST = 4003; /** * Request denied because the end user's account could not cover the requested service */ int CREDIT_CONTROL_LIMIT_REACHED = 4012; /** * The peer received a message that contained an AVP that is not recognized or supported and was marked with the * Mandatory bit. A Diameter message with this error MUST contain one or more Failed- AVP AVP containing the AVPs * that caused the failure. */ int AVP_UNSUPPORTED = 5001; /** * The request contained an unknown Session-Id. */ int UNKNOWN_SESSION_ID = 5002; /** * A request was received for which the user could not be authorized. This error could occur if the service * requested is not permitted to the user. */ int AUTHORIZATION_REJECTED = 5003; /** * The request contained an AVP with an invalid value in its data portion. A Diameter message indicating this error * MUST include the offending AVPs within a Failed-AVP AVP. */ int INVALID_AVP_VALUE = 5004; /** * The request did not contain an AVP that is required by the Command Code definition. If this value is sent in the * Result-Code AVP, a Failed-AVP AVP SHOULD be included in the message. The Failed-AVP AVP MUST contain an example * of the missing AVP complete with the Vendor-Id if applicable. The value field of the missing AVP should be of * correct minimum length and contain zeroes. */ int MISSING_AVP = 5005; /** * A request was received that cannot be authorized because the user has already expended allowed resources. An * example of this error condition is a user that is restricted to one dial-up PPP port, attempts to establish a * second PPP connection. */ int RESOURCES_EXCEEDED = 5006; /** * The Home Diameter server has detected AVPs in the request that contradicted each other, and is not willing to * provide service to the user. One or more Failed-AVP AVPs MUST be present, containing the AVPs that contradicted * each other. */ int CONTRADICTING_AVPS = 5007; /** * A message was received with an AVP that MUST NOT be present. The Failed-AVP AVP MUST be included and contain a * copy of the offending AVP. */ int AVP_NOT_ALLOWED = 5008; /** * A message was received that included an AVP that appeared more often than permitted in the message definition. * The Failed-AVP AVP MUST be included and contain a copy of the first instance of the offending AVP that exceeded * the maximum number of occurrences */ int AVP_OCCURS_TOO_MANY_TIMES = 5009; /** * This error is returned when a CER message is received, and there are no common applications supported between the * peers. */ int NO_COMMON_APPLICATION = 5010; /** * This error is returned when a request was received, whose version number is unsupported. */ int UNSUPPORTED_VERSION = 5011; /** * This error is returned when a request is rejected for unspecified reasons. */ int UNABLE_TO_COMPLY = 5012; /** * This error is returned when an unrecognized bit in the Diameter header is set to one (1). */ int INVALID_BIT_IN_HEADER = 5013; /** * The request contained an AVP with an invalid length. A Diameter message indicating this error MUST include the * offending AVPs within a Failed-AVP AVP. */ int INVALID_AVP_LENGTH = 5014; /** * This error is returned when a request is received with an invalid message length. */ int INVALID_MESSAGE_LENGTH = 5015; /** * The request contained an AVP with which is not allowed to have the given value in the AVP Flags field. A * Diameter message indicating this error MUST include the offending AVPs within a Failed-AVP AVP. */ int INVALID_AVP_BIT_COMBO = 5016; /** * This error is returned when a CER message is received, and there are no common security mechanisms supported * between the peers. A Capabilities-Exchange-Answer (CEA) MUST be returned with the Result-Code AVP set to * DIAMETER_NO_COMMON_SECURITY. */ int NO_COMMON_SECURITY = 5017; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/RouteException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * The NoRouteException signals that no route exist for a given realm. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public class RouteException extends Exception { private static final long serialVersionUID = 1L; /** * Constructor with reason string * * @param message reason string */ public RouteException(String message) { super(message); } /** * Constructor with reason string and parent exception * * @param message message reason string * @param cause parent exception */ public RouteException(String message, Throwable cause) { super(message, cause); } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Selector.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * @author erick.svenson@yahoo.com */ @SuppressWarnings("all") //3rd party lib public interface Selector { /** * Return true if rule is true * * @param object check object * * @return true if rule is true */ boolean checkRule(T object); /** * Return metainformation object * * @return metainformation object */ A getMetaData(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Session.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * This interface append to base interface specific methods for creating and send diameter requests and responses * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Session extends BaseSession, Wrapper { /** * Set session request listener * * @param listener session request listener */ void setRequestListener(NetworkReqListener listener); /** * Returns a new Request object with the specified command code, applicationId, realm and predefined system avps. * * @param commandCode code of message * @param appId applicationId of destination application * @param destRealm name of destination Realm * * @return new message object */ Request createRequest(int commandCode, ApplicationId appId, String destRealm); /** * Returns a new Request object with the specified command code, applicationId, realm, host and predefined system * avps. * * @param commandCode code of message * @param appId applicationId of destination application * @param destRealm name of destination Realm * @param destHost name of destination Host * * @return new Request object */ Request createRequest(int commandCode, ApplicationId appId, String destRealm, String destHost); /** * Returns a new Request object base on previous request.(header is copied) * * @param prevRequest previous request (header is copied) * * @return new Request object */ Request createRequest(Request prevRequest); /** * Sends and wait response message with default timeout * * @param message request/answer diameter message * @param listener event listener * * @throws org.jdiameter.api.InternalException The InternalException signals that internal error is * occurred. * @throws org.jdiameter.api.IllegalDiameterStateException The IllegalStateException signals that session has * incorrect state (invalid). * @throws org.jdiameter.api.RouteException The NoRouteException signals that no route exist for a * given realm. * @throws org.jdiameter.api.OverloadException The OverloadException signals that destination host is * overloaded. */ void send(Message message, EventListener listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Sends and wait response message with defined timeout * * @param message request/answer diameter message * @param listener event listener * @param timeOut value of timeout * @param timeUnit type of timeOut value * * @throws org.jdiameter.api.InternalException The InternalException signals that internal error is * occurred. * @throws org.jdiameter.api.IllegalDiameterStateException The IllegalStateException signals that session has * incorrect state (invalid). * @throws org.jdiameter.api.RouteException The NoRouteException signals that no route exist for a * given realm. * @throws org.jdiameter.api.OverloadException The OverloadException signals that destination host is * overloaded. */ void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Sends and wait response message with default timeout * * @param message request/answer diameter message * * @return InFuture result of an asynchronous operation * * @throws org.jdiameter.api.InternalException The InternalException signals that internal error is * occurred. * @throws org.jdiameter.api.IllegalDiameterStateException The IllegalStateException signals that session has * incorrect state (invalid). * @throws org.jdiameter.api.RouteException The NoRouteException signals that no route exist for a * given realm. * @throws org.jdiameter.api.OverloadException The OverloadException signals that destination host is * overloaded. */ Future send(Message message) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Sends and wait response message with defined timeout * * @param message request/answer diameter message * @param timeOut value of timeout * @param timeUnit type of timeOut value * * @return InFuture result of an asynchronous operation * * @throws org.jdiameter.api.InternalException The InternalException signals that internal error is * occurred. * @throws org.jdiameter.api.IllegalDiameterStateException The IllegalStateException signals that session has * incorrect state (invalid). * @throws org.jdiameter.api.RouteException The NoRouteException signals that no route exist for a * given realm. * @throws org.jdiameter.api.OverloadException The OverloadException signals that destination host is * overloaded. */ Future send(Message message, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/SessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import org.jdiameter.api.app.AppSession; /** * This class created session instance (Factory) * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface SessionFactory { /** * Generates new session id which can be used as argument in {@link #getNewSession(String)} or {@link * #getNewAppSession(String, ApplicationId, Class)}. * * @return new id for session. * * @since 1.5.4.1-build416 */ String getSessionId(); /** * See {@link #getSessionId()}. This method has similar semantics, it adds custom part to id. * * @param customPart * * @return * * @since 1.5.4.1-build416 */ String getSessionId(String customPart); /** * Create new raw session instance * * @return session instance of session * * @throws InternalException if a error occurs */ RawSession getNewRawSession() throws InternalException; /** * Create new session with new session id * * @return session instance of session * * @throws InternalException if a error occurs */ Session getNewSession() throws InternalException; /** * Create new session with predefined sessionId You can create special sessions to work on distributed systems * * @param sessionId instance of session * * @return session instance of session * * @throws InternalException if a error occurs */ Session getNewSession(String sessionId) throws InternalException; /** * Create new vendor specific application session Use this method for create specific application sessions Example: * ClientShSession session = factory.getNewSession(appId, ClientShSession.class) * * @param applicationId predefined application id * @param userSession A Class defining an interface that the result must implement. * * @return session instance * * @throws InternalException if a error occurs */ T getNewAppSession(ApplicationId applicationId, Class userSession) throws InternalException; /** * Create new vendor specific application session with predefined sessionId, origination host/realm names. You can * create special sessions to work on distributed systems Use this method for create specific application sessions * Example: ClientShSession session = factory.getNewSession(appId, ClientShSession.class) * * @param sessionId instance of session * @param applicationId predefined application id * @param userSession A Class defining an interface that the result must implement. * * @return session instance * * @throws InternalException if a error occurs */ T getNewAppSession(String sessionId, ApplicationId applicationId, Class userSession) throws InternalException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Stack.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import org.jdiameter.api.validation.Dictionary; /** * The interface that every stack class must implement. The Java Diameter framework allows for multiple database stacks. * Each stack should supply a class that implements the Stack interface. The StackManager will try to load as many * stacks. It is strongly recommended that each Stack class should be small and standalone. When a Stack class is * loaded, it should create an instance of itself and register it with the StackManager. This means that a user can load * and register a stack by calling Class.forName("org.jdiameter.impl.Stack") *

      * Wrapper interface allows adapt message to any driver vendor specific interface *
      * Life cycle state machine for stack *

      * *

      *

      * Stack must supported following wrapper classes: - Client API : PeerManager - Server API : PeerManager, * OverloadManager (Network, PeerManagerWrapper is optional) * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Stack extends Wrapper { /** * Configuration stack and allocation system resources. * * @param config Object with configuration parameters * * @return instance of session factory (DataSource equals) * * @throws IllegalDiameterStateException if a stack already configured or destroyed * @throws InternalException if a stack can not processing initial procedure */ SessionFactory init(Configuration config) throws IllegalDiameterStateException, InternalException; /** * Start activity of stack (Thread and Network connections), not waiting switch ANY peer to OKEY state * * @throws IllegalDiameterStateException if a stack is not configured or stopped * @throws InternalException if a stack can not processing start procedure */ void start() throws IllegalDiameterStateException, InternalException; /** * Start activity of stack (Thread and Network connections), waiting specified wait time switch peers to OKEY * state. * * @param mode specified type of wait procedure * @param timeout how long to wait before giving up, in units of unit * @param unit a TimeUnit determining how to interpret the timeout parameter * * @throws IllegalDiameterStateException if a stack is not configured or stopped * @throws InternalException if a stack can not processing start procedure */ void start(Mode mode, long timeout, TimeUnit unit) throws IllegalDiameterStateException, InternalException; /** * Stop any activity of stack (Thread and Network connections), waiting if necessary up to the specified wait time * switch peers to DOWN state. * * @param timeout how long to wait before giving up, in units of unit * @param unit a TimeUnit determining how to interpret the timeout parameter * @param disconnectCause the disconnect-cause to be used in the DPR message(s) * * @throws IllegalDiameterStateException if a stack is not started * @throws InternalException if a stack can not processing start procedure */ void stop(long timeout, TimeUnit unit, int disconnectCause) throws IllegalDiameterStateException, InternalException; /** * Destroy any resource append to this instance of stack */ void destroy(); /** * @return true is stack is running. */ boolean isActive(); /** * Return logger instance. You can set your logger handler and processing logger alarms in application. * * @return logger interface */ Logger getLogger(); /** * Return SessionFactory instance * * @return SessionFactory instance * * @throws IllegalDiameterStateException if stack is not configured */ SessionFactory getSessionFactory() throws IllegalDiameterStateException; /** * Return Dictionary instance * * @return Dictionary instance * * @throws IllegalDiameterStateException if stack is not configured */ Dictionary getDictionary() throws IllegalDiameterStateException; /** * @return stack meta information */ MetaData getMetaData(); /** * Return an existing session, if present * * @param sessionId the session identifier * @param clazz the class of the session object * * @return the session object if it exists, null otherwise * * @throws InternalException if stack is not configured */ T getSession(String sessionId, Class clazz) throws InternalException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/StackManager.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.io.PrintWriter; import java.security.PrivilegedAction; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** *

      * The basic service for managing a set of Diameter stacks.
      * *

      * As part of its initialization, the DriverManager class will * attempt to load the stacks classes referenced in the "diameter.drivers" system property. This allows a user to * customize the Diameter Drivers used by their applications. For example in your ~/.hotjava/properties file you might * specify: * *

       * diameter.drivers=foo.bah.Stack:wombat.diameter.Stack
       * 
      *

      * A program can also explicitly load Diameter stacks at any time. For example, the my.diameter.Stack is loaded with the * following statement: * *

       * Class.forName("my.diameter.Stack");
       * 
      * *

      * When the method getSession is called, * the StackManager will attempt to locate a suitable stack from amongst those loaded at initialization and * those loaded explicitly using the same classloader as the current applet or application. * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public final class StackManager { private static final Object logSync = new Object(); private static List stacks = new CopyOnWriteArrayList(); private static PrintWriter logWriter = null; private static boolean initialized = false; static void initialize() { if (initialized) { return; } initialized = true; loadInitialStacks(); println("Diameter StackManager initialized"); } private StackManager() { } /** * Retrieves the log writer. *

      * The getLogWriter and setLogWriter methods should be used instead of the * get/setlogStream methods, which are deprecated. * * @return a java.io.PrintWriter object * * @see #setLogWriter */ public static PrintWriter getLogWriter() { synchronized (logSync) { return logWriter; } } /** * Sets the logging/tracing PrintWriter object that is used by the StackManager and all * drivers. *

      * There is a minor versioning problem created by the introduction of the method setLogWriter. The * method setLogWriter cannot create a PrintStream object that will be returned by * getLogStream * * @param out the new logging/tracing PrintStream object; * null to disable logging and tracing * * @throws SecurityException if a security manager exists and its * checkPermission method denies * setting the log writer */ public static void setLogWriter(java.io.PrintWriter out) { synchronized (logSync) { logWriter = out; } } /** * Attempts to locate a stack. The StackManager attempts to select an appropriate stack from the set of * registered Diameter stacks. * * @param className class name of stack * * @return stack instance * * @throws InternalException if a manager has internal error */ public static synchronized Stack getStack(String className) throws InternalException { println(new StringBuilder().append("StackManager.getStack(\"").append(className).append("\")").toString()); if (!initialized) { initialize(); } // Gets the classloader of the code that called this method, may be null. ClassLoader callerCL = ClassLoader.getSystemClassLoader(); // Walk through the loaded stacks attempting to locate someone who understands the given URL. for (StackInfo di : stacks) { // If the caller does not have permission to load the stack then skip it. if (getCallerClass(callerCL, di.stackClassName) != di.stackClass) { println(new StringBuilder().append(" skipping: ").append(di).toString()); continue; } println(new StringBuilder().append(" trying ").append(di).toString()); if (di.stackClassName.equals(className)) { // Success! println("geStack returning " + di); return (di.stack); } } println("getStack: no suitable stack"); throw new InternalException("No suitable stack"); } /** * Registers the given stack with the ScoketManager. A newly-loaded stack class should call the method * registerStack to make itself known to the StackManager. * * @param stack the new Diameter Stack that is to be registered with the * StackManager * * @throws InternalException if a manager has internal error */ public static synchronized void registerStack(Stack stack) throws InternalException { if (!initialized) { initialize(); } StackInfo stackInfo = new StackInfo(); stackInfo.stack = stack; stackInfo.stackClass = stack.getClass(); stackInfo.stackClassName = stackInfo.stackClass.getName(); stacks.add(stackInfo); println(new StringBuilder().append("registerStack: ").append(stackInfo).toString()); } /** * Drops a driver from the DiameterManager's list. Applets can only deregister stacks from their own * classloaders. * * @param stack the Diameter stack to drop * * @throws InternalException if a manager has internal error */ public static synchronized void deregisterStack(Stack stack) throws InternalException { // Gets the classloader of the code that called this method, may be null. ClassLoader callerCL = ClassLoader.getSystemClassLoader(); println(new StringBuilder().append("StackManager.deregisterStack: ").append(stack).toString()); // Walk through the loaded stacks. int i; StackInfo stackInfo = null; for (i = 0; i < stacks.size(); i++) { stackInfo = stacks.get(i); if (stackInfo.stack == stack) { break; } } // If we can't find the stack just return. if (i >= stacks.size()) { println(" couldn't find stack to unload"); return; } // If the caller does not have permission to load the stack then throw a security exception. if (stackInfo == null || getCallerClass(callerCL, stackInfo.stackClassName) != stackInfo.stackClass) { throw new SecurityException(); } // Remove the stack. Other entries in stacks get shuffled down. stacks.remove(i); } /** * Retrieves an Enumeration with all of the currently loaded Diameter stacks to which the current caller has * access. * *

      * Note: The classname of a stack can be found using * d.getClass().getName() * * @return the list of Diameter stacks loaded by the caller's class loader */ public static synchronized Enumeration getStacks() { List result = new CopyOnWriteArrayList(); if (!initialized) { initialize(); } // Gets the classloader of the code that called this method, may be null. ClassLoader callerCL = ClassLoader.getSystemClassLoader(); // Walk through the loaded stacks. for (StackInfo di : stacks) { // If the caller does not have permission to load the stack then skip it. if (getCallerClass(callerCL, di.stackClassName) != di.stackClass) { println(new StringBuilder().append(" skipping: ").append(di).toString()); continue; } result.add(di.stack); } return Collections.enumeration(result); } public static void println(String message) { synchronized (logSync) { if (logWriter != null) { logWriter.println(message); // automatic flushing is never enabled, so we must do it ourselves logWriter.flush(); } } } @SuppressWarnings("all") //3rd party lib private static Class getCallerClass(ClassLoader callerClassLoader, String stackClassName) { Class callerC; try { callerC = Class.forName(stackClassName, true, callerClassLoader); } catch (Exception ex) { callerC = null; } return callerC; } private static void loadInitialStacks() { String stacks; try { stacks = System.getProperty("diameter.stacks"); } catch (Exception ex) { stacks = null; } println(new StringBuilder().append("StackManager.initialize: diameter.stacks = ").append(stacks).toString()); if (stacks == null) { return; } while (stacks.length() != 0) { int x = stacks.indexOf(':'); String stack; if (x < 0) { stack = stacks; stacks = ""; } else { stack = stacks.substring(0, x); stacks = stacks.substring(x + 1); } if (stack.length() == 0) { continue; } try { println(new StringBuilder().append("StackManager.Initialize: loading ").append(stack).toString()); Class.forName(stack, true, ClassLoader.getSystemClassLoader()); } catch (Exception ex) { println(new StringBuilder().append("StackManager.Initialize: load failed: ").append(ex).toString()); } } } } class GetPropertyAction implements PrivilegedAction { private String theProp; private String defaultVal; GetPropertyAction(String s) { theProp = s; } GetPropertyAction(String s, String s1) { theProp = s; defaultVal = s1; } @Override public String run() { String s = System.getProperty(theProp); return s != null ? s : defaultVal; } } @SuppressWarnings("all") //3rd party lib class StackInfo { Stack stack; Class stackClass; String stackClassName; @Override public String toString() { return (new StringBuilder().append("stack[className=").append(stackClassName).append(",").append(stack).append("]") .toString()); } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/StackType.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This enumerated class define type of jDiameter stacks * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ public enum StackType { TYPE_CLIENT, TYPE_SERVER } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Statistic.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This class is container for statistics information. For example: Count Request/Answer messages * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Statistic { /** * Return name of statistic * * @return name of statistic */ String getName(); /** * Return description of statistic * * @return description of statistic */ String getDescription(); /** * Enable/Disable collecting statistics * * @param value true for enable statistic */ void enable(boolean value); /** * Return true is statistic is collecting * * @return true is statistic is collecting */ boolean isEnabled(); /** * Reset all counter in statistic */ void reset(); /** * Return counters of statistics * * @return counters of statistics */ StatisticRecord[] getRecords(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/StatisticRecord.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * This class implements counter of statistic * * @author erick.svenson@yahoo.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface StatisticRecord { /** * Return name of counter * * @return name of counter */ String getName(); /** * Return description of counter * * @return description of counter */ String getDescription(); /** * Return value of counter as integer * * @return value of counter */ int getValueAsInt(); /** * Return value of counter as double * * @return value of counter */ double getValueAsDouble(); /** * Return value of counter as long * * @return value of counter */ long getValueAsLong(); /** * Return child counters * * @return array of child counters */ StatisticRecord[] getChilds(); /** * Reset counter and all child counters */ void reset(); /** * Enable/Disable counter * * @param e on/off parameter */ void enable(boolean e); boolean isEnabled(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/URI.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; import java.io.Serializable; import java.net.URISyntaxException; import java.net.UnknownServiceException; /** * This class handles Diameter URIs. It only implements parts that are needed for the Diameter URI * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Yulian Oifa * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public final class URI implements Comparable, Serializable { private static final long serialVersionUID = 1L; private static final String FIELD_PROTOCOL = "protocol="; private static final String FIELD_TRANSPORT = "transport="; private static final String SCHEME_SEPARATOR = "://"; private static final String PARAMS_SEPARATOR = ";"; private static final String DEFAULT_SCHEME = "aaa"; private static final int DEFAULT_PORT = 3868; private String scheme; private String host; private int port = -1; private String path = ""; /** * Constructor with string parameter * * @param uri String representation of URI * * @throws URISyntaxException which signals that URI has syntax error * @throws UnknownServiceException which signals that URI has incorrect scheme */ public URI(String uri) throws URISyntaxException, UnknownServiceException { parse(uri); if (getFQDN() == null || getFQDN().trim().length() == 0) { throw new URISyntaxException(uri, "Host not found"); } if (!getScheme().equals("aaa") && !getScheme().equals("aaas")) { throw new UnknownServiceException( new StringBuilder().append("Unsupported service: ").append(getScheme()).toString()); } } /** * @return scheme for URI */ public String getScheme() { return scheme; } /** * @return host name of URI */ public String getFQDN() { return host; } /** * Returns the port number of this URI, or -1 if this is not set. * * @return the port number of this URI */ public int getPort() { return port == -1 ? DEFAULT_PORT : port; } /** * @return true if this URI is secure */ public boolean isSecure() { return getScheme().endsWith("s"); } /** * @return path of this URI */ public String getPath() { return path; } /** * @return protocol parameter of this URI */ public String getProtocolParam() { String[] args = getPath().split(PARAMS_SEPARATOR); for (String arg : args) { if (arg.startsWith(FIELD_PROTOCOL)) { return arg.substring(FIELD_PROTOCOL.length()); } } return null; } /** * @return transport parameter of this URI */ public String getTransportParam() { String[] args = getPath().split(PARAMS_SEPARATOR); for (String arg : args) { if (arg.startsWith(FIELD_TRANSPORT)) { return arg.substring(FIELD_TRANSPORT.length()); } } return null; } /** * @return String representation of this URI in RFC 3588 format */ @Override public String toString() { StringBuffer rc = new StringBuffer(scheme).append(SCHEME_SEPARATOR).append(host); if (port != -1) { rc.append(":").append(port); } if (path != null && path.length() > 0) { rc.append(PARAMS_SEPARATOR).append(path); } return rc.toString(); } private void parse(String uri) throws URISyntaxException { try { int schemeStartIndex = uri.indexOf(SCHEME_SEPARATOR); int schemeEndIndex = 0; if (schemeStartIndex == -1) { scheme = DEFAULT_SCHEME; } else { scheme = uri.substring(0, schemeStartIndex); schemeEndIndex = schemeStartIndex + 3; schemeStartIndex = uri.indexOf(';', schemeEndIndex); } if (schemeStartIndex == -1) { host = uri.substring(schemeEndIndex); } else { host = uri.substring(schemeEndIndex, schemeStartIndex); } int sepIndex = host.indexOf(':'); if (sepIndex != -1) { port = Integer.parseInt(host.substring(sepIndex + 1)); host = host.substring(0, sepIndex); } if (schemeStartIndex != -1) { path = uri.substring(schemeStartIndex + 1); } } catch (Exception e) { throw new URISyntaxException(uri, "URI has incorrect format"); } } /** * Indicates whether some other object is "equal to" this one. *

      * The equals method implements an equivalence relation on non-null object references: *

        *
      • It is reflexive: for any non-null reference value * x, x.equals(x) should return * true. *
      • It is symmetric: for any non-null reference values * x and y, x.equals(y) * should return true if and only if * y.equals(x) returns true. *
      • It is transitive: for any non-null reference values * x, y, and z, if * x.equals(y) returns true and * y.equals(z) returns true, then * x.equals(z) should return true. *
      • It is consistent: for any non-null reference values * x and y, multiple invocations of * x.equals(y) consistently return true * or consistently return false, provided no * information used in equals comparisons on the * objects is modified. *
      • For any non-null reference value x, * x.equals(null) should return false. *
      *

      * The equals method for class Object implements * the most discriminating possible equivalence relation on objects; * that is, for any non-null reference values x and * y, this method returns true if and only * if x and y refer to the same object * (x == y has the value true). *

      * Note that it is generally necessary to override the hashCode * method whenever this method is overridden, so as to maintain the * general contract for the hashCode method, which states * that equal objects must have equal hash codes. * * @param obj the reference object with which to compare. * * @return true if this object is the same as the obj * argument; false otherwise. * * @see #hashCode() * @see java.util.Hashtable */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } URI that = (URI) obj; return getPort() == that.getPort() && !(host != null ? !host.equals(that.host) : that.host != null) && !(path != null ? !path.equals(that.path) : that.path != null) && !(scheme != null ? !scheme.equals(that.scheme) : that.scheme != null); } /** * Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those * provided by * java.util.Hashtable. *

      * The general contract of hashCode is: *

        *
      • Whenever it is invoked on the same object more than once during * an execution of a Java application, the hashCode method * must consistently return the same integer, provided no information * used in equals comparisons on the object is modified. * This integer need not remain consistent from one execution of an * application to another execution of the same application. *
      • If two objects are equal according to the equals(Object) * method, then calling the hashCode method on each of * the two objects must produce the same integer result. *
      • It is not required that if two objects are unequal * according to the {@link java.lang.Object#equals(java.lang.Object)} * method, then calling the hashCode method on each of the * two objects must produce distinct integer results. However, the * programmer should be aware that producing distinct integer results * for unequal objects may improve the performance of hashtables. *
      *

      * As much as is reasonably practical, the hashCode method defined by * class Object does return distinct integers for distinct * objects. (This is typically implemented by converting the internal * address of the object into an integer, but this implementation * technique is not required by the * JavaTM programming language.) * * @return a hash code value for this object. * * @see java.lang.Object#equals(java.lang.Object) * @see java.util.Hashtable */ @Override public int hashCode() { int result; result = (scheme != null ? scheme.hashCode() : 0); result = 31 * result + (host != null ? host.hashCode() : 0); result = 31 * result + getPort(); result = 31 * result + (path != null ? path.hashCode() : 0); return result; } /** * Compares this object with the specified object for order. Returns a negative integer, zero, or a positive * integer as this object is less than, equal to, or greater than the specified object. *

      *

      * In the foregoing description, the notation * sgn(expression) designates the mathematical * signum function, which is defined to return one of -1, * 0, or 1 according to whether the value of expression * is negative, zero or positive. *

      * The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and * y. (This implies that x.compareTo(y) must throw an exception iff * y.compareTo(x) throws an exception.) *

      *

      * The implementor must also ensure that the relation is transitive: * (x.compareTo(y)>0 && y.compareTo(z)>0) implies * x.compareTo(z)>0. *

      *

      * Finally, the implementer must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == * sgn(y.compareTo(z)), for all z. *

      *

      * It is strongly recommended, but not strictly required that * (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any * class that implements the Comparable interface and violates this condition should clearly indicate this * fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals." * * @param obj the Object to be compared. * * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than * the specified object. * * @throws ClassCastException if the specified object's type prevents it from being compared to this Object. */ @Override public int compareTo(Object obj) { if (obj instanceof URI) { return this.toString().compareTo(obj.toString()); } else { return -1; } } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/Wrapper.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api; /** * Interface for JDiameter classes which provide the ability to retrieve the delegate instance when the instance in * question is in fact a proxy class. The wrapper pattern is employed by many JDiameter stack implementations to provide * extensions beyond the traditional JDiameter API that are specific to a data source. Developers may wish to gain * access to these resources that are wrapped ( the delegates) as proxy class instances representing the the actual * resources. This interface describes a standard mechanism to access these wrapped resources represented by their * proxy, to permit direct access to the resource delegates. * * @author erick.svenson@yahoo.com * @author artem.litvinov@gmail.com * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface Wrapper { /** * Returns true if this either implements the interface argument or is directly or indirectly a wrapper for an * object that does. Returns false otherwise. If this implements the interface then return true, else if t his is a * wrapper then return the result of recursively calling isWrapperFor on the wrapped object. If this does not * implement the interface and is not a wrapper, return false. This method should be implemented as a low-cost * operation compared to unwrap so that callers can use this method to avoid expensive unwrap calls that may fail. * If this method returns true then calling unwrap with the same argument should succeed. * * @param iface A Class defining an interface that the result must implement. * * @return true if this implements the interface or directly or indirectly wraps an object that does. * * @throws InternalException If no object found that implements the interface */ boolean isWrapperFor(java.lang.Class iface) throws InternalException; /** * Returns an object that implements the given interface to allow access to non-standard methods, or standard * methods not exposed by the proxy. The result may be either the object found to implement the interface or a proxy * for that object. If the receiver implements the interface then that is the object. If the receiver is a wrapper * and the wrapped object implements the interface then that is the object. Otherwise the object is the result of * calling unwrap recursively on the wrapped object. If the receiver is not a wrapper and does not implement the * interface, then an SQLException is thrown. * * @param iface A Class defining an interface that the result must implement. * * @return an object that implements the interface. May be a proxy for the actual implementing object. * * @throws InternalException If no object found that implements the interface */ T unwrap(java.lang.Class iface) throws InternalException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/acc/ClientAccSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.acc; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; /** * Basic class for accounting application specific session Listener must injection from constructor of implementation * class * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ClientAccSession extends AppSession, StateMachine { /** * Send Account Request to Server * * @param request request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalStateException The IllegalStateException signals that session has incorrect state (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendAccountRequest(AccountRequest request) throws InternalException, IllegalStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/acc/ClientAccSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.acc; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.acc.events.AccountAnswer; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; /** * This interface defines the possible actions that the different states in the Accounting state machine * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ClientAccSessionListener { /** * Notifies this AccSessionEventListener that the ClientAccSesssion has recived AccAnswer message. * * @param appSession parent application session (FSM) * @param request accounting request object * @param answer accounting answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doAccAnswerEvent(ClientAccSession appSession, AccountRequest request, AccountAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AccSessionEventListener that the ClientAccSesssion has recived not account message. * * @param appSession parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/acc/ServerAccSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.acc; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.acc.events.AccountAnswer; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; /** * Basic class for server accounting application specific session. Listener must injection from constructor of * implementation class. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ServerAccSession extends AppSession, StateMachine { /** * Send Account Answer to Client * * @param answer request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalStateException The IllegalStateException signals that session has incorrect state (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendAccountAnswer(AccountAnswer answer) throws InternalException, IllegalStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/acc/ServerAccSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.acc; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; /** * This interface defines the possible actions that the different states in the Accounting state machine * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ServerAccSessionListener { /** * Notifies this AccSessionEventListener that the ServerAccSesssion has recived AccRequest message. * * @param appSession parent application session (FSM) * @param request accounting request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doAccRequestEvent(ServerAccSession appSession, AccountRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ServerAuthSesssion has recived not authentication message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/acc/events/AccountAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.acc.events; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppAnswerEvent; /** * An Answer message is sent by a recipient of Request once it has received and interpreted the Request. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface AccountAnswer extends AppAnswerEvent { String _SHORT_NAME = "ACA"; String _LONG_NAME = "Accounting-Answer"; int code = 271; /** * @return Record type of answer * * @throws org.jdiameter.api.AvpDataException if result code avp is not integer */ int getAccountingRecordType() throws AvpDataException; /** * @return record number * * @throws AvpDataException if result code avp is not integer */ long getAccountingRecordNumber() throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/acc/events/AccountRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.acc.events; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppRequestEvent; /** * An Account Request is a request from a client to a server * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface AccountRequest extends AppRequestEvent { String _SHORT_NAME = "ACR"; String _LONG_NAME = "Accounting-Request"; int code = 271; /** * @return Record type of request * * @throws AvpDataException if result code avp is not integer */ int getAccountingRecordType() throws AvpDataException; /** * @return record number * * @throws AvpDataException if result code avp is not integer */ long getAccountingRecordNumber() throws AvpDataException; /** * @param recordType * * @throws AvpDataException */ void setAccountingRecordType(int recordType) throws AvpDataException; /** * @param number * * @throws AvpDataException */ void setAccountingRecordNumber(long number) throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/annotation/AvpDscr.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * This annotation allows describe Java POJO object as Diameter avp element * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface AvpDscr { /** * Return avp code * * @return avp code */ int code(); /** * Return avp name * * @return avp name */ String name() default "unknown"; /** * Return avp type * * @return avp type */ AvpType type(); /** * Return avp vendor id * * @return avp vendor id */ long vendorId() default 0; /** * Return array of mandatory flags * * @return array of mandatory flags */ AvpFlag[] must() default {}; /** * Return array optional flags * * @return array optional flags */ AvpFlag[] may() default {}; /** * Return array flags which should not be set * * @return array flags which should not be set */ AvpFlag[] shldNot() default {}; /** * Return array flags which must not be set * * @return array flags which must not be set */ AvpFlag[] mustNot() default {}; /** * Return true if the flag can be encrypted * * @return true if the flag can be encrypted */ boolean mayEncr() default false; /** * Return array of avp child ( for grouped avp ) * * @return array of avp child */ Child[] childs() default {}; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/annotation/AvpFlag.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.annotation; /** * This enumerated class describe all flags of avp header * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ public enum AvpFlag { /** * Mandatory flag */ M, /** * Vendor-Id flag */ V, /** * Encryption flag */ P } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/annotation/AvpType.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.annotation; /** * This enumerated class describe base type of avp. For more information look RFC 3588 * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public enum AvpType { OctetString, Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64, Grouped, Address, Time, UTF8String, DiameterIdentity, DiameterURI, Enumerated, IPFilterRule, QoSFilterRule } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/annotation/Child.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * This annotation allow describe information about child of command / group avp * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Child { /** * Return reference to child class or interface with AvpDscr annotation * * @return reference to child class or interface with AvpDscr annotation */ Class ref(); /** * Return child position * * @return child position */ int pos() default -1; /** * Return minimum count of this child in parent avp set * * @return minimum count of this child in parent avp set */ int min() default 0; /** * Return maximum count of this child in parent avp set * * @return maximum count of this child in parent avp set s */ int max() default 1; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/annotation/CommandDscr.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * This annotation allows describe Java POJO object as Diameter Command element * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface CommandDscr { /** * Return command code * * @return command code */ int code(); /** * Return command name * * @return command name */ String name() default "unknown"; /** * Return array of command flags * * @return array of command flags */ CommandFlag[] flags() default {}; /** * Return command application-id * * @return command application-id */ long appId() default 0; /** * Return array of command child avp * * @return array of command child avp */ Child[] childs() default {}; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/annotation/CommandFlag.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.annotation; /** * This enumerated class describe all flags of message * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ public enum CommandFlag { /** * Request flag */ R, /** * Proxiable flag */ P, /** * Error flag */ E, /** * Re-transmitted flag */ T, } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/annotation/Getter.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * This annotation allows get child object from command / group avp and get value for simple avp * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.CONSTRUCTOR, ElementType.METHOD }) public @interface Getter { } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/annotation/Setter.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * This annotation allows set child object to command / group avp and set value to simple avp * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.CONSTRUCTOR, ElementType.METHOD }) public @interface Setter { /** * This enumeration defines for what Avp (known/not known) is used setter */ enum Type { /** * For known avp */ DEFINED, /** * For unknown avp */ UNDEFINED } /** * Return type of setter * * @return type of setter */ Type value() default Type.DEFINED; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/app/AppAnswerEvent.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.app; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; /** * Basic class for application specific answer event (Sx, Rx, Gx) * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface AppAnswerEvent extends AppEvent { /** * Return result code (or experimental if present) AVP of answer message * * @return result code (or experimental if present) AVP of answer message * * @throws AvpDataException if result code avp absent */ Avp getResultCodeAvp() throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/app/AppEvent.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.app; import java.io.Serializable; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; /** * Basic class for application specific event (Sx, Rx, Gx) * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface AppEvent extends Serializable { /** * @return commCode of parent message */ int getCommandCode(); /** * @return set of associated message * * @throws InternalException signals that internal message is not set. */ Message getMessage() throws InternalException; /** * Return origination host avp value ( null if avp is empty ) * * @return origination host avp value * * @throws AvpDataException if avp is not string */ String getOriginHost() throws AvpDataException; /** * Return origination realm avp value ( null if avp is empty ) * * @return origination realm avp value * * @throws AvpDataException if avp is not string */ String getOriginRealm() throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/app/AppRequestEvent.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.app; import org.jdiameter.api.AvpDataException; /** * Basic class for application specific request event (Sx, Rx, Gx) * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface AppRequestEvent extends AppEvent { /** * Return destination host avp value ( null if avp is empty ) * * @return destination host avp value * * @throws AvpDataException if avp is not string */ String getDestinationHost() throws AvpDataException; /** * Return destination realm avp value ( null if avp is empty ) * * @return origination realm avp value * * @throws AvpDataException if avp is not string */ String getDestinationRealm() throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/app/AppSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.app; import java.util.List; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.BaseSession; import org.jdiameter.api.Session; /** * Basic class for application specific session (Sx, Rx, Gx) * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface AppSession extends BaseSession { /** * Return true if session has stateless FSM * * @return true if session has stateless FSM */ boolean isStateless(); /** * Return current value of applicationId of application session. * * @return applicationId of application session. */ ApplicationId getSessionAppId(); /** * Returns a list of child sessions * * @return List of child delivery sessions */ List getSessions(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/app/State.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.app; /** * This interface must be extended by any class that should implement a certain state in the state machine. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface State { /** * Action that should be taken each time this state is entered */ void entryAction(); /** * Action that should be taken each time this state is exited */ void exitAction(); /** * This method processed received event. * * @param event the event to process. * * @return true if event is processed */ boolean processEvent(StateEvent event); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/app/StateChangeListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.app; /** * Interface used to inform about changes in the state for a FSM. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface StateChangeListener { /** * @param oldState Old state of FSM * @param newState New state of FSM * * @deprecated A change of state has occurred for a FSM. */ @Deprecated @SuppressWarnings("unchecked") void stateChanged(Enum oldState, Enum newState); /** * A change of state has occurred for a FSM. * * @param source the App Session that generated the change. * @param oldState Old state of FSM * @param newState New state of FSM */ @SuppressWarnings("unchecked") void stateChanged(T source, Enum oldState, Enum newState); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/app/StateEvent.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.app; /** * The Event class holds information about the different events that can be handled by the state machine. Events are * prioritized depending on the importance of the event. The priority model tries to ensure that old messages are * handled before any new ones. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface StateEvent extends Comparable { /** * This method should be adapted by any subclass to return the type corresponding to the actual event. * * @return type of this StateEvent */ E encodeType(Class enumType); /** * Return type of this StateEvent * * @return type of this StateEvent */ Enum getType(); /** * Returns a negative value if the priority for this object * is higher than the priority for the supplied object. * * @param obj the Event to compare to. * @return compare result */ /** * Set information object to this StateEvent * * @param data information object */ void setData(Object data); /** * Return information object of this StateEvent * * @return information object of this StateEvent */ Object getData(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/app/StateMachine.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.app; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; /** * The StateMachine lets you organize event handling, if the order of the events are important to you. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface StateMachine { /** * Add a new state change listener * * @param listener a reference to the listener that will get information about state changes. */ void addStateChangeNotification(StateChangeListener listener); /** * Remove a state change listener * * @param listener a reference to the listener that will get information about state changes. */ void removeStateChangeNotification(StateChangeListener listener); /** * Handle an event in the current state. * * @param event processing event * * @return true if staterocessed * * @throws OverloadException if queue of state mashine is full * @throws InternalException if FSM has internal error */ boolean handleEvent(StateEvent event) throws InternalException, OverloadException; /** * Get the current state * * @param stateType type of state * * @return current state */ E getState(Class stateType); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/ClientAuthSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.auth.events.AbortSessionAnswer; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.SessionTermRequest; /** * Basic class for authentication application specific session Listener must injection from constructor of * implementation class * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ClientAuthSession extends AppSession, StateMachine { /** * Send authentication session request to server * * @param request Authentication-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendAuthRequest(AppRequestEvent request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send re-authentication session answer to server * * @param answer Re-Authentication-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send abort session answer to server * * @param answer Abort-Session-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded */ void sendAbortSessionAnswer(AbortSessionAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send session termination request to server * * @param request Session-Term-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendSessionTerminationRequest(SessionTermRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/ClientAuthSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.events.AbortSessionRequest; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.auth.events.SessionTermAnswer; /** * This interface defines the possible actions that the different states in the Authentication state machine * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ClientAuthSessionListener { /** * Notifies this AuthSessionEventListener that the ClientAuthSesssion has recived AuthAnswer message. * * @param session parent application session (FSM) * @param request authentication request object * @param answer authentication answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doAuthAnswerEvent(ClientAuthSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ClientAuthSesssion has recived ReAuthRequest message. * * @param session parent application session (FSM) * @param request re-authentication request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doReAuthRequestEvent(ClientAuthSession session, ReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ClientAuthSesssion has recived AbortSessionRequest message. * * @param session parent application session (FSM) * @param request abort session request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doAbortSessionRequestEvent(ClientAuthSession session, AbortSessionRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ClientAuthSesssion has recived SessionTerminationAnswer message. * * @param session parent application session (FSM) * @param answer abort session request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doSessionTerminationAnswerEvent(ClientAuthSession session, SessionTermAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ClientAuthSesssion has recived not authentication message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/ServerAuthSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.auth.events.AbortSessionRequest; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.auth.events.SessionTermAnswer; /** * Basic class for server authentication application specific session. Listener must injection from constructor of * implementation class. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ServerAuthSession extends AppSession, StateMachine { /** * Send authenticate answer to client * * @param answer Authentication answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendAuthAnswer(AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send re-authenticate request to client * * @param request Re-Authentication request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendReAuthRequest(ReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send session abort session request to client * * @param request Abort-Session-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendAbortSessionRequest(AbortSessionRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send session termination answer to client * * @param request Session-Term-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendSessionTerminationAnswer(SessionTermAnswer request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/ServerAuthSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.events.AbortSessionAnswer; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.auth.events.SessionTermRequest; /** * This interface defines the possible actions that the different states in the Authentication state machine * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ServerAuthSessionListener { /** * Notifies this AuthSessionEventListener that the ServerAuthSesssion has recived AuthRequest message. * * @param session parent application session (FSM) * @param request authentication request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doAuthRequestEvent(ServerAuthSession session, AppRequestEvent request) throws InternalException, org.jdiameter.api.IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ServerAuthSesssion has recived ReAuthAnswer message. * * @param session parent application session (FSM) * @param request re-authentication request object * @param answer re-authentication answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doReAuthAnswerEvent(ServerAuthSession session, ReAuthRequest request, ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ServerAuthSesssion has recived AbortSessionRequest message. * * @param session parent application session (FSM) * @param answer abort session event event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doAbortSessionAnswerEvent(ServerAuthSession session, AbortSessionAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ServerAuthSesssion has recived SessionTerminationRequest * message. * * @param session parent application session (FSM) * @param request session termination request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doSessionTerminationRequestEvent(ServerAuthSession session, SessionTermRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ServerAuthSesssion has recived not authentication message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/events/AbortSessionAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth.events; import org.jdiameter.api.app.AppAnswerEvent; /** * A Answer message is sent by a recipient of Request once it has received and interpreted the Request. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface AbortSessionAnswer extends AppAnswerEvent { String _SHORT_NAME = "ASA"; String _LONG_NAME = "Abort-Session-Answer"; int code = 274; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/events/AbortSessionRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth.events; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppRequestEvent; /** * A Abort Session Request is a request from a client to a server * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface AbortSessionRequest extends AppRequestEvent { String _SHORT_NAME = "ASR"; String _LONG_NAME = "Abort-Session-Request"; int code = 274; /** * Return Auth-Application-Id value of request * * @return Auth-Application-Id value of request * * @throws org.jdiameter.api.AvpDataException if avp is not integer */ long getAuthApplicationId() throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/events/ReAuthAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth.events; import org.jdiameter.api.app.AppAnswerEvent; /** * A Answer message is sent by a recipient of Request once it has received and interpreted the Request. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ReAuthAnswer extends AppAnswerEvent { String _SHORT_NAME = "RAA"; String _LONG_NAME = "Re-Auth-Answer"; int code = 258; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/events/ReAuthRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth.events; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppRequestEvent; /** * A ReAuthentication Request is a request from a client to a server * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface ReAuthRequest extends AppRequestEvent { String _SHORT_NAME = "RAR"; String _LONG_NAME = "Re-Auth-Request"; int code = 258; /** * Return re-authentication request type * * @return re-authentication request type * * @throws org.jdiameter.api.AvpDataException if avp is not integer */ int getReAuthRequestType() throws AvpDataException; /** * Return Auth-Application-Id value of request * * @return Auth-Application-Id value of request * * @throws AvpDataException if avp is not integer */ long getAuthApplicationId() throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/events/SessionTermAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth.events; import org.jdiameter.api.app.AppAnswerEvent; /** * A Answer message is sent by a recipient of Request once it has received and interpreted the Request. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface SessionTermAnswer extends AppAnswerEvent { String _SHORT_NAME = "STA"; String _LONG_NAME = "Session-Termination-Answer"; int code = 275; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/auth/events/SessionTermRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.auth.events; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppRequestEvent; /** * A Session Termination Request is a request from a client to a server * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.1 Final */ @SuppressWarnings("all") //3rd party lib public interface SessionTermRequest extends AppRequestEvent { String _SHORT_NAME = "STR"; String _LONG_NAME = "Session-Termination-Request"; int code = 275; /** * @return Auth-Application-Id value of request * * @throws AvpDataException if result code avp is not integer */ long getAuthApplicationId() throws AvpDataException; /** * @return termination cause * * @throws AvpDataException if result code avp is not integer */ int getTerminationCause() throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cca/CCASession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cca; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface CCASession extends AppSession, StateMachine { // simple marker interface. } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cca/ClientCCASession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cca; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; /** * Basic class for client credit-control application specific session Listener must be injected from constructor of * implementation class * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientCCASession extends CCASession { /** * Send credit-control request to server * * @param request Credit-Control-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendCreditControlRequest(JCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send re-authentication answer to server * * @param answer Re-Auth-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cca/ClientCCASessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cca; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; /** * This interface defines the possible actions for the different states in the client Credit-Control Application state * machine. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientCCASessionListener { /** * Notifies this ClientCCASessionListener that the ClientCCASession has received a CCA message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doCreditControlAnswer(ClientCCASession session, JCreditControlRequest request, JCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ClientCCASessionListener that the ClientCCASession has received a RAR message. * * @param session parent application session (FSM) * @param request request object * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ default void doReAuthRequest(ClientCCASession session, ReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } /** * Notifies this ClientCCASessionListener that the ClientCCASession has received a non CCA message, usually some * extension. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ default void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } /** * Provides with default value of DDFH AVP - this is used when AVP is not present or send operation fails for some * reason.
      * DDFH is of type Enumerated - int32 * * @return */ default int getDefaultDDFHValue() { return 0; } /** * Provides with default value of CCFH AVP - this is used when AVP is not present or send operation fails for some * reason.
      * CCFH is of type Enumerated - int32 * * @return */ default int getDefaultCCFHValue() { return 0; } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cca/ServerCCASession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cca; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.cca.events.JCreditControlAnswer; /** * Basic class for server credit-control application specific session Listener must be injected from constructor of * implementation class * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ServerCCASession extends CCASession { /** * Send credit-control answer to client * * @param answer Credit-Control-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendCreditControlAnswer(JCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send re-authentication request to client * * @param request Re-Auth-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendReAuthRequest(ReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cca/ServerCCASessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cca; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.cca.events.JCreditControlRequest; /** * This interface defines the possible actions for the different states in the server Credit-Control Application state * machine. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ServerCCASessionListener { /** * Notifies this ServerCCASessionListener that the ServerCCASession has received a CCR message. * * @param session parent application session (FSM) * @param request request object * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doCreditControlRequest(ServerCCASession session, JCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ServerCCASessionListener that the ServerCCASession has received a RAA message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ default void doReAuthAnswer(ServerCCASession session, ReAuthRequest request, ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } /** * Notifies this ServerCCASessionListener that the ServerCCASession has received not CCA message, now it can be even * RAA. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ default void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cca/events/JCreditControlAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cca.events; import org.jdiameter.api.Avp; import org.jdiameter.api.app.AppAnswerEvent; /** * The Credit-Control-Answer message (CCA) is indicated by the command-code field being set to 272 and the 'R' bit being * cleared in the Command Flags field. It is used between the credit-control server and the Diameter credit-control * client to acknowledge a Credit-Control-Request command. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JCreditControlAnswer extends AppAnswerEvent { String _SHORT_NAME = "CCA"; String _LONG_NAME = "Credit-Control-Answer"; int code = 272; boolean isCreditControlFailureHandlingAVPPresent(); int getCredidControlFailureHandlingAVPValue(); boolean isDirectDebitingFailureHandlingAVPPresent(); int getDirectDebitingFailureHandlingAVPValue(); boolean isRequestTypeAVPPresent(); int getRequestTypeAVPValue(); Avp getValidityTimeAvp(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cca/events/JCreditControlRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cca.events; import org.jdiameter.api.app.AppRequestEvent; /** * The Credit-Control-Request message (CCR) is indicated by the command-code field being set to 272 and the 'R' bit * being set in the Command Flags field. It is used between the Diameter credit-control client and the credit-control * server to request credit authorization for a given service. *

      * The Auth-Application-Id MUST be set to the value 4, indicating the Diameter credit-control application. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JCreditControlRequest extends AppRequestEvent { String _SHORT_NAME = "CCR"; String _LONG_NAME = "Credit-Control-Request"; int code = 272; boolean isRequestedActionAVPPresent(); int getRequestedActionAVPValue(); boolean isRequestTypeAVPPresent(); int getRequestTypeAVPValue(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/ClientCxDxSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.cxdx.events.JLocationInfoRequest; import org.jdiameter.api.cxdx.events.JMultimediaAuthRequest; import org.jdiameter.api.cxdx.events.JPushProfileAnswer; import org.jdiameter.api.cxdx.events.JRegistrationTerminationAnswer; import org.jdiameter.api.cxdx.events.JServerAssignmentRequest; import org.jdiameter.api.cxdx.events.JUserAuthorizationRequest; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientCxDxSession extends AppSession, StateMachine { void sendUserAuthorizationRequest(JUserAuthorizationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendServerAssignmentRequest(JServerAssignmentRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendLocationInformationRequest(JLocationInfoRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendMultimediaAuthRequest(JMultimediaAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendRegistrationTerminationAnswer(JRegistrationTerminationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendPushProfileAnswer(JPushProfileAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/ClientCxDxSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.cxdx.events.JLocationInfoAnswer; import org.jdiameter.api.cxdx.events.JLocationInfoRequest; import org.jdiameter.api.cxdx.events.JMultimediaAuthAnswer; import org.jdiameter.api.cxdx.events.JMultimediaAuthRequest; import org.jdiameter.api.cxdx.events.JPushProfileRequest; import org.jdiameter.api.cxdx.events.JRegistrationTerminationRequest; import org.jdiameter.api.cxdx.events.JServerAssignmentAnswer; import org.jdiameter.api.cxdx.events.JServerAssignmentRequest; import org.jdiameter.api.cxdx.events.JUserAuthorizationAnswer; import org.jdiameter.api.cxdx.events.JUserAuthorizationRequest; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientCxDxSessionListener { /** * Notifies this ClientCxDxSessionListener that the ClientCxDxSession has recived not CxDx message, usually some * extension. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doUserAuthorizationAnswer(ClientCxDxSession session, JUserAuthorizationRequest request, JUserAuthorizationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doServerAssignmentAnswer(ClientCxDxSession session, JServerAssignmentRequest request, JServerAssignmentAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doRegistrationTerminationRequest(ClientCxDxSession session, JRegistrationTerminationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doLocationInformationAnswer(ClientCxDxSession session, JLocationInfoRequest request, JLocationInfoAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doPushProfileRequest(ClientCxDxSession session, JPushProfileRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doMultimediaAuthAnswer(ClientCxDxSession session, JMultimediaAuthRequest request, JMultimediaAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/ServerCxDxSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.cxdx.events.JLocationInfoAnswer; import org.jdiameter.api.cxdx.events.JMultimediaAuthAnswer; import org.jdiameter.api.cxdx.events.JPushProfileRequest; import org.jdiameter.api.cxdx.events.JRegistrationTerminationRequest; import org.jdiameter.api.cxdx.events.JServerAssignmentAnswer; import org.jdiameter.api.cxdx.events.JUserAuthorizationAnswer; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ServerCxDxSession extends AppSession, StateMachine { void sendUserAuthorizationAnswer(JUserAuthorizationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendServerAssignmentAnswer(JServerAssignmentAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendLocationInformationAnswer(JLocationInfoAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendMultimediaAuthAnswer(JMultimediaAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendRegistrationTerminationRequest(JRegistrationTerminationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendPushProfileRequest(JPushProfileRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/ServerCxDxSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.cxdx.events.JLocationInfoRequest; import org.jdiameter.api.cxdx.events.JMultimediaAuthRequest; import org.jdiameter.api.cxdx.events.JPushProfileAnswer; import org.jdiameter.api.cxdx.events.JPushProfileRequest; import org.jdiameter.api.cxdx.events.JRegistrationTerminationAnswer; import org.jdiameter.api.cxdx.events.JRegistrationTerminationRequest; import org.jdiameter.api.cxdx.events.JServerAssignmentRequest; import org.jdiameter.api.cxdx.events.JUserAuthorizationRequest; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ServerCxDxSessionListener { /** * Notifies this ClientCxDxSessionListener that the ClientCxDxSession has recived not CxDx message, usually some * extension. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doUserAuthorizationRequest(ServerCxDxSession session, JUserAuthorizationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doServerAssignmentRequest(ServerCxDxSession session, JServerAssignmentRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doRegistrationTerminationAnswer(ServerCxDxSession session, JRegistrationTerminationRequest request, JRegistrationTerminationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doLocationInformationRequest(ServerCxDxSession session, JLocationInfoRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doPushProfileAnswer(ServerCxDxSession session, JPushProfileRequest request, JPushProfileAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doMultimediaAuthRequest(ServerCxDxSession session, JMultimediaAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JLocationInfoAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The Location-Info-Answer (LIA) command, indicated by the Command-Code field set to 302 and the bit cleared in the * Command Flags field, is sent by a server in response to the Location-Info-Request command. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JLocationInfoAnswer extends AppAnswerEvent { String _SHORT_NAME = "LIA"; String _LONG_NAME = "Location-Info-Answer"; int code = 302; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JLocationInfoRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The Location-Info-Request (LIR) command, indicated by the Command-Code field set to 302 and the bit set in the * Command Flags field, is sent by a Diameter Multimedia client to a Diameter Multimedia server in order to request name * of the server that is currently serving the user. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JLocationInfoRequest extends AppRequestEvent { String _SHORT_NAME = "LIR"; String _LONG_NAME = "Location-Info-Request"; int code = 302; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JMultimediaAuthAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The Multimedia-Auth-Answer (MAA) command, indicated by the Command-Code field set to 303 and the bit cleared in the * Command Flags field, is sent by a server in response to the Multimedia-Auth-Request command. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JMultimediaAuthAnswer extends AppAnswerEvent { String _SHORT_NAME = "MAA"; String _LONG_NAME = "Multimedia-Auth-Answer"; int code = 303; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JMultimediaAuthRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The Multimedia-Auth-Request (MAR) command, indicated by the Command-Code field set to 303 and the bit set in the * Command Flags field, is sent by a Diameter Multimedia client to a Diameter Multimedia server in order to request * security information. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JMultimediaAuthRequest extends AppRequestEvent { String _SHORT_NAME = "MAR"; String _LONG_NAME = "Multimedia-Auth-Request"; int code = 303; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JPushProfileAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The Push-Profile-Answer (PPA) command, indicated by the Command-Code field set to 305 and the bit cleared in the * Command Flags field, is sent by a client in response to the Push-Profile-Request command. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JPushProfileAnswer extends AppAnswerEvent { String _SHORT_NAME = "PPA"; String _LONG_NAME = "Push-Profile-Answer"; int code = 305; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JPushProfileRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The Push-Profile-Request (PPR) command, indicated by the Command-Code field set to 305 and the bit set in the Command * Flags field, is sent by a Diameter Multimedia server to a Diameter Multimedia client in order to update the * subscription data and for SIP Digest authentication the authentication data of a multimedia user in the Diameter * Multimedia client whenever a modification has occurred in the subscription data or digest password that constitutes * the data used by the client. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JPushProfileRequest extends AppRequestEvent { String _SHORT_NAME = "PPR"; String _LONG_NAME = "Push-Profile-Request"; int code = 305; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JRegistrationTerminationAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The Registration-Termination-Answer (RTA) command, indicated by the Command-Code field set to 304 and the bit cleared * in the Command Flags field, is sent by a client in response to the Registration-Termination-Request command. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JRegistrationTerminationAnswer extends AppAnswerEvent { String _SHORT_NAME = "RTA"; String _LONG_NAME = "Registration-Termination-Answer"; int code = 304; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JRegistrationTerminationRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The Registration-Termination-Request (RTR) command, indicated by the Command-Code field set to 304 and the bit set in * the Command Flags field, is sent by a Diameter Multimedia server to a Diameter Multimedia client in order to request * the de-registration of a user. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JRegistrationTerminationRequest extends AppRequestEvent { String _SHORT_NAME = "RTR"; String _LONG_NAME = "Registration-Termination-Request"; int code = 304; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JServerAssignmentAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The Server-Assignment-Answer (SAA) command, indicated by the Command-Code field set to 301 and the bit cleared in the * Command Flags field, is sent by a server in response to the Server-Assignment-Request command. If Result-Code or * Experimental-Result does not inform about an error, the User-Data AVP shall contain the information that the S-CSCF * needs to give service to the user. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JServerAssignmentAnswer extends AppAnswerEvent { String _SHORT_NAME = "SAA"; String _LONG_NAME = "Server-Assignment-Answer"; int code = 301; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JServerAssignmentRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The Server-Assignment-Request (SAR) command, indicated by the Command-Code field set to 301 and the bit set in the * Command Flags field, is sent by a Diameter Multimedia client to a Diameter Multimedia server in order to request it * to store the name of the server that is currently serving the user. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JServerAssignmentRequest extends AppRequestEvent { String _SHORT_NAME = "SAR"; String _LONG_NAME = "Server-Assignment-Request"; int code = 301; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JUserAuthorizationAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The User-Authorization-Answer (UAA) command, indicated by the Command-Code field set to 300 and the bit cleared in * the Command Flags field, is sent by a server in response to the User-Authorization-Request command. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JUserAuthorizationAnswer extends AppAnswerEvent { String _SHORT_NAME = "UAA"; String _LONG_NAME = "User-Authorization-Answer"; int code = 300; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/cxdx/events/JUserAuthorizationRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.cxdx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The User-Authorization-Request (UAR) command, indicated by the Command-Code field set to 300 and the bit set in the * Command Flags field, is sent by a Diameter Multimedia client to a Diameter Multimedia server in order to request the * authorization of the registration of a multimedia user. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JUserAuthorizationRequest extends AppRequestEvent { String _SHORT_NAME = "UAR"; String _LONG_NAME = "User-Authorization-Request"; int code = 300; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gq/ClientGqSessionListener.java ================================================ package org.jdiameter.api.gq; import org.jdiameter.api.auth.ClientAuthSessionListener; public interface ClientGqSessionListener extends ClientAuthSessionListener { } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gq/GqClientSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gq; import org.jdiameter.api.auth.ClientAuthSession; /** * Basic class for Client Gq application specific session Listener must be injected from constructor of implementation * class * * @author Yulian Oifa * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface GqClientSession extends ClientAuthSession { } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gq/GqServerSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gq; import org.jdiameter.api.auth.ServerAuthSession; /** * Basic class for Server Gq application specific session Listener must be injected from constructor of implementation * class * * @author Yulian Oifa * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface GqServerSession extends ServerAuthSession { } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gq/ServerGqSessionListener.java ================================================ package org.jdiameter.api.gq; import org.jdiameter.api.auth.ServerAuthSessionListener; public interface ServerGqSessionListener extends ServerAuthSessionListener { } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gx/ClientGxSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.gx.events.GxCreditControlRequest; import org.jdiameter.api.gx.events.GxReAuthAnswer; /** * Basic class for Gx client credit-control application specific session. Listener must be injected from constructor of * implementation class. * * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface ClientGxSession extends AppSession, StateMachine { /** * Send credit-control request to server. * * @param request Credit-Control-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendCreditControlRequest(final GxCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send re-authentication answer to server * * @param answer Re-Auth-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendGxReAuthAnswer(final GxReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gx/ClientGxSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.gx.events.GxCreditControlAnswer; import org.jdiameter.api.gx.events.GxCreditControlRequest; import org.jdiameter.api.gx.events.GxReAuthRequest; /** * This interface defines the possible actions for the different states in the client Credit-Control Application state * machine. * * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface ClientGxSessionListener { /** * Notifies this ClientGxSessionListener that the ClientGxSession has received a Ro message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doCreditControlAnswer(ClientGxSession session, GxCreditControlRequest request, GxCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ClientGxSessionListener that the ClientGxSession has received a RAR message. * * @param session parent application session (FSM) * @param request request object * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ default void doGxReAuthRequest(ClientGxSession session, GxReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } /** * Notifies this ClientGxSessionListener that the ClientGxSession has received a non Gx message, usually some * extension. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ default void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } /** * Provides with default value of DDFH AVP - this is used when AVP is not present or send operation fails for some * reason.
      * DDFH is of type Enumerated - int32 * * @return */ default int getDefaultDDFHValue() { return 0; } /** * Provides with default value of CCFH AVP - this is used when AVP is not present or send operation fails for some * reason.
      * CCFH is of type Enumerated - int32 * * @return */ default int getDefaultCCFHValue() { return 0; } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gx/ServerGxSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.gx.events.GxCreditControlAnswer; import org.jdiameter.api.gx.events.GxReAuthRequest; /** * Basic class for server credit-control application specific session. Listener must be injected from constructor of * implementation class * * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface ServerGxSession extends AppSession, StateMachine { /** * Send credit-control answer to client * * @param answer Credit-Control-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendCreditControlAnswer(GxCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send re-authentication request to client * * @param request Re-Auth-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendGxReAuthRequest(GxReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gx/ServerGxSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.gx.events.GxCreditControlRequest; import org.jdiameter.api.gx.events.GxReAuthAnswer; import org.jdiameter.api.gx.events.GxReAuthRequest; /** * This interface defines the possible actions for the different states in the server Credit-Control Application state * machine. * * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface ServerGxSessionListener { /** * Notifies this ServerRoSessionListener that the ServerRoSession has received a CCR message. * * @param session parent application session (FSM) * @param request request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doCreditControlRequest(ServerGxSession session, GxCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ServerRoSessionListener that the ServerRoSession has received a RAA message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doGxReAuthAnswer(ServerGxSession session, GxReAuthRequest request, GxReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ServerRoSessionListener that the ServerRoSession has received not Ro message, now it can be even * RAA. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gx/events/GxCreditControlAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gx.events; import org.jdiameter.api.Avp; import org.jdiameter.api.app.AppAnswerEvent; /** * The Credit-Control-Answer (CCA) messages, indicated by the Command-Code field set to 272 is sent by the OCF to the * CTF in order to reply to the CCR. * * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface GxCreditControlAnswer extends AppAnswerEvent { String _SHORT_NAME = "CCA"; String _LONG_NAME = "Credit-Control-Answer"; int code = 272; boolean isCreditControlFailureHandlingAVPPresent(); int getCredidControlFailureHandlingAVPValue(); boolean isDirectDebitingFailureHandlingAVPPresent(); int getDirectDebitingFailureHandlingAVPValue(); boolean isRequestTypeAVPPresent(); int getRequestTypeAVPValue(); Avp getValidityTimeAvp(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gx/events/GxCreditControlRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The CCR messages, indicated by the Command-Code field set to 272 is sent by the CTF to the OCF in order to request * credits for the request bearer / subsystem / service. * * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface GxCreditControlRequest extends AppRequestEvent { String _SHORT_NAME = "CCR"; String _LONG_NAME = "Credit-Control-Request"; int code = 272; boolean isRequestedActionAVPPresent(); int getRequestedActionAVPValue(); boolean isRequestTypeAVPPresent(); int getRequestTypeAVPValue(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gx/events/GxReAuthAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The Credit-Control-Answer (CCA) messages, indicated by the Command-Code field set to 272 is sent by the OCF to the * CTF in order to reply to the CCR. * * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface GxReAuthAnswer extends AppAnswerEvent { String _SHORT_NAME = "RAA"; String _LONG_NAME = "Re-Auth-Answer"; int code = 258; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/gx/events/GxReAuthRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.gx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The CCR messages, indicated by the Command-Code field set to 272 is sent by the CTF to the OCF in order to request * credits for the request bearer / subsystem / service. * * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface GxReAuthRequest extends AppRequestEvent { String _SHORT_NAME = "RAR"; String _LONG_NAME = "Re-Auth-Request"; int code = 258; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rf/ClientRfSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rf; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.rf.events.RfAccountingRequest; /** * Basic class for Rf accounting application specific session Listener must injection from constructor of implementation * class * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientRfSession extends AppSession, StateMachine { /** * Send Account Request to Server * * @param request request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalStateException The IllegalStateException signals that session has incorrect state (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendAccountRequest(RfAccountingRequest request) throws InternalException, IllegalStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rf/ClientRfSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rf; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rf.events.RfAccountingAnswer; import org.jdiameter.api.rf.events.RfAccountingRequest; /** * This interface defines the possible actions that the different states in the Accounting state machine. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientRfSessionListener { /** * Notifies this AccSessionEventListener that the ClientAccSesssion has received AccAnswer message. * * @param appSession parent application session (FSM) * @param request accounting request object * @param answer accounting answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doRfAccountingAnswerEvent(ClientRfSession appSession, RfAccountingRequest request, RfAccountingAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AccSessionEventListener that the ClientAccSesssion has received not account message. * * @param appSession parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rf/ServerRfSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rf; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.rf.events.RfAccountingAnswer; /** * Basic class for server Rf accounting application specific session. Listener must injection from constructor of * implementation class. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ServerRfSession extends AppSession, StateMachine { /** * Send Account Answer to Client * * @param answer request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalStateException The IllegalStateException signals that session has incorrect state (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendAccountAnswer(RfAccountingAnswer answer) throws InternalException, IllegalStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rf/ServerRfSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rf; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rf.events.RfAccountingRequest; /** * This interface defines the possible actions that the different states in the Accounting state machine * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ServerRfSessionListener { /** * Notifies this AccSessionEventListener that the ServerAccSesssion has recived AccRequest message. * * @param appSession parent application session (FSM) * @param request accounting request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doRfAccountingRequestEvent(ServerRfSession appSession, RfAccountingRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this AuthSessionEventListener that the ServerAuthSesssion has recived not authentication message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rf/events/RfAccountingAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rf.events; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppAnswerEvent; /** * The Accounting Answer (ACA) messages, indicated by the Command-Code field set to 271 is sent by the CDF to the CTF in * order to reply to the ACR. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface RfAccountingAnswer extends AppAnswerEvent { String _SHORT_NAME = "ACA"; String _LONG_NAME = "Accounting-Answer"; int code = 271; /** * @return Record type of answer * * @throws org.jdiameter.api.AvpDataException if result code avp is not integer */ int getAccountingRecordType() throws AvpDataException; /** * @return record number * * @throws AvpDataException if result code avp is not integer */ long getAccountingRecordNumber() throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rf/events/RfAccountingRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rf.events; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppRequestEvent; /** * The ACR messages, indicated by the Command-Code field set to 271 is sent by the CTF to the CDF in order to send * charging information for the request bearer / subsystem / service. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface RfAccountingRequest extends AppRequestEvent { String _SHORT_NAME = "ACR"; String _LONG_NAME = "Accounting-Request"; int code = 271; /** * @return Record type of request * * @throws AvpDataException if result code avp is not integer */ int getAccountingRecordType() throws AvpDataException; /** * @return record number * * @throws AvpDataException if result code avp is not integer */ long getAccountingRecordNumber() throws AvpDataException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.ro; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.ro.events.RoCreditControlRequest; /** * Basic class for Ro client credit-control application specific session Listener must be injected from constructor of * implementation class * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientRoSession extends AppSession, StateMachine { /** * Send credit-control request to server * * @param request Credit-Control-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendCreditControlRequest(RoCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send re-authentication answer to server * * @param answer Re-Auth-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ClientRoSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.ro; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.ro.events.RoCreditControlAnswer; import org.jdiameter.api.ro.events.RoCreditControlRequest; /** * This interface defines the possible actions for the different states in the client Credit-Control Application state * machine. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientRoSessionListener { /** * Notifies this ClientRoSessionListener that the ClientRoSession has received a Ro message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doCreditControlAnswer(ClientRoSession session, RoCreditControlRequest request, RoCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ClientRoSessionListener that the ClientRoSession has received a RAR message. * * @param session parent application session (FSM) * @param request request object * * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doReAuthRequest(ClientRoSession session, ReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ClientRoSessionListener that the ClientRoSession has received a non Ro message, usually some * extension. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error has occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Provides with default value of DDFH AVP - this is used when AVP is not present or send operation fails for some * reason.
      * DDFH is of type Enumerated - int32 * * @return */ int getDefaultDDFHValue(); /** * Provides with default value of CCFH AVP - this is used when AVP is not present or send operation fails for some * reason.
      * CCFH is of type Enumerated - int32 * * @return */ int getDefaultCCFHValue(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ServerRoSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.ro; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.ro.events.RoCreditControlAnswer; /** * Basic class for server credit-control application specific session Listener must be injected from constructor of * implementation class * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ServerRoSession extends AppSession, StateMachine { /** * Send credit-control answer to client * * @param answer Credit-Control-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendCreditControlAnswer(RoCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send re-authentication request to client * * @param request Re-Auth-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendReAuthRequest(ReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ro/ServerRoSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.ro; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.ro.events.RoCreditControlRequest; /** * This interface defines the possible actions for the different states in the server Credit-Control Application state * machine. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ServerRoSessionListener { /** * Notifies this ServerRoSessionListener that the ServerRoSession has received a CCR message. * * @param session parent application session (FSM) * @param request request object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doCreditControlRequest(ServerRoSession session, RoCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ServerRoSessionListener that the ServerRoSession has received a RAA message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doReAuthAnswer(ServerRoSession session, ReAuthRequest request, ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ServerRoSessionListener that the ServerRoSession has received not Ro message, now it can be even * RAA. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ro/events/RoCreditControlAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.ro.events; import org.jdiameter.api.Avp; import org.jdiameter.api.app.AppAnswerEvent; /** * The Credit-Control-Answer (CCA) messages, indicated by the Command-Code field set to 272 is sent by the OCF to the * CTF in order to reply to the CCR. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface RoCreditControlAnswer extends AppAnswerEvent { String _SHORT_NAME = "CCA"; String _LONG_NAME = "Credit-Control-Answer"; int code = 272; boolean isCreditControlFailureHandlingAVPPresent(); int getCredidControlFailureHandlingAVPValue(); boolean isDirectDebitingFailureHandlingAVPPresent(); int getDirectDebitingFailureHandlingAVPValue(); boolean isRequestTypeAVPPresent(); int getRequestTypeAVPValue(); Avp getValidityTimeAvp(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/ro/events/RoCreditControlRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.ro.events; import org.jdiameter.api.app.AppRequestEvent; /** * The CCR messages, indicated by the Command-Code field set to 272 is sent by the CTF to the OCF in order to request * credits for the request bearer / subsystem / service. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface RoCreditControlRequest extends AppRequestEvent { String _SHORT_NAME = "CCR"; String _LONG_NAME = "Credit-Control-Request"; int code = 272; boolean isRequestedActionAVPPresent(); int getRequestedActionAVPValue(); boolean isRequestTypeAVPPresent(); int getRequestTypeAVPValue(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/ClientRxSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.rx.events.RxAARequest; import org.jdiameter.api.rx.events.RxAbortSessionAnswer; import org.jdiameter.api.rx.events.RxReAuthAnswer; import org.jdiameter.api.rx.events.RxSessionTermRequest; /** * Basic class for Rx Client Interface specific session. Listener must be injected from constructor of implementation * class. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ClientRxSession extends AppSession, StateMachine { void sendAARequest(final RxAARequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendSessionTermRequest(final RxSessionTermRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendReAuthAnswer(final RxReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendAbortSessionAnswer(final RxAbortSessionAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/ClientRxSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rx.events.*; /** * This interface defines the possible actions for the different states in the client Rx Interface state machine. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ClientRxSessionListener { void doAAAnswer(ClientRxSession session, RxAARequest request, RxAAAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; default void doReAuthRequest(ClientRxSession session, RxReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } default void doSessionTermAnswer(ClientRxSession session, RxSessionTermRequest request, RxSessionTermAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } default void doAbortSessionRequest(ClientRxSession session, RxAbortSessionRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } default void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/ServerRxSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.rx.events.RxAAAnswer; import org.jdiameter.api.rx.events.RxAbortSessionRequest; import org.jdiameter.api.rx.events.RxReAuthRequest; import org.jdiameter.api.rx.events.RxSessionTermAnswer; /** * Basic class for Rx Server Interface specific session. Listener must be injected from constructor of implementation * class * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ServerRxSession extends AppSession, StateMachine { void sendAAAnswer(RxAAAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendSessionTermAnswer(RxSessionTermAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendReAuthRequest(RxReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendAbortSessionRequest(RxAbortSessionRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/ServerRxSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rx.events.*; /** * This interface defines the possible actions for the different states in the server Rx Interface state machine. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ServerRxSessionListener { void doAARequest(ServerRxSession session, RxAARequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; default void doSessionTermRequest(ServerRxSession session, RxSessionTermRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } default void doReAuthAnswer(ServerRxSession session, RxReAuthRequest request, RxReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } default void doAbortSessionAnswer(ServerRxSession session, RxAbortSessionRequest request, RxAbortSessionAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } default void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/events/RxAAAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The AAA command, indicated by the Command-Code field set to 265 and the 'R' bit cleared in the Command Flags field, * is sent by the PCRF to the AF in response to the AAR command. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface RxAAAnswer extends AppAnswerEvent { String _SHORT_NAME = "AAA"; String _LONG_NAME = "AA-Answer"; int code = 265; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/events/RxAARequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The AAR command, indicated by the Command-Code field set to 265 and the 'R' bit set in the Command Flags field, is * sent by an AF to the PCRF in order to provide it with the Session Information. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface RxAARequest extends AppRequestEvent { String _SHORT_NAME = "AAR"; String _LONG_NAME = "AA-Request"; int code = 265; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/events/RxAbortSessionAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The ASA command, indicated by the Command-Code field set to 274 and the 'R' bit cleared in the Command Flags field, * is sent by the AF to the PCRF in response to the ASR command. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface RxAbortSessionAnswer extends AppAnswerEvent { String _SHORT_NAME = "ASA"; String _LONG_NAME = "Abort-Session-Answer"; int code = 274; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/events/RxAbortSessionRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The ASR command, indicated by the Command-Code field set to 274 and the 'R' bit set in the Command Flags field, is * sent by a PCRF to the AF in order to abort a session. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface RxAbortSessionRequest extends AppRequestEvent { String _SHORT_NAME = "ASR"; String _LONG_NAME = "Abort-Session-Request"; int code = 274; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/events/RxReAuthAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The RAA command, indicated by the Command-Code field set to 258 and the 'R' bit cleared in the Command Flags field, * is sent by the AF to the PCRf in response to the RAR command. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface RxReAuthAnswer extends AppAnswerEvent { String _SHORT_NAME = "RAA"; String _LONG_NAME = "Re-Auth-Answer"; int code = 258; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/events/RxReAuthRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The RAR command, indicated by the Command-Code field set to 258 and the 'R' bit set in the Command Flags field, is * sent by an PCRF to the AF in order to provide it with the Session Information. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface RxReAuthRequest extends AppRequestEvent { String _SHORT_NAME = "RAR"; String _LONG_NAME = "Re-Auth-Request"; int code = 258; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/events/RxSessionTermAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The STA command, indicated by the Command-Code field set to 275 and the 'R' bit cleared in the Command Flags field, * is sent by the PCRF to the AF in response to the STR command. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface RxSessionTermAnswer extends AppAnswerEvent { String _SHORT_NAME = "STA"; String _LONG_NAME = "Session-Termination-Answer"; int code = 275; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/rx/events/RxSessionTermRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.rx.events; import org.jdiameter.api.app.AppRequestEvent; /** * The STR command, indicated by the Command-Code field set to 275 and the 'R' bit set in the Command Flags field, is * sent by an AF to the PCRF in order to terminate a session. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface RxSessionTermRequest extends AppRequestEvent { String _SHORT_NAME = "STR"; String _LONG_NAME = "Session-Termination-Request"; int code = 275; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s13/ClientS13Session.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.api.s13; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.s13.events.JMEIdentityCheckRequest; @SuppressWarnings("all") //3rd party lib public interface ClientS13Session extends AppSession, StateMachine { /** * Send ME-Identity-Check-Request to server * * @param request ME-Identity-Check-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendMEIdentityCheckRequest(JMEIdentityCheckRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s13/ClientS13SessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.api.s13; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.s13.events.JMEIdentityCheckAnswer; import org.jdiameter.api.s13.events.JMEIdentityCheckRequest; @SuppressWarnings("all") //3rd party lib public interface ClientS13SessionListener { void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doMEIdentityCheckAnswerEvent(ClientS13Session session, JMEIdentityCheckRequest request, JMEIdentityCheckAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s13/ServerS13Session.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.api.s13; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.s13.events.JMEIdentityCheckAnswer; @SuppressWarnings("all") //3rd party lib public interface ServerS13Session extends AppSession, StateMachine { /** * Send ME-Identity-Check-Answer to client * * @param answer ME-Identity-Check-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendMEIdentityCheckAnswer(JMEIdentityCheckAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s13/ServerS13SessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.api.s13; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.s13.events.JMEIdentityCheckRequest; @SuppressWarnings("all") //3rd party lib public interface ServerS13SessionListener { void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doMEIdentityCheckRequestEvent(ServerS13Session session, JMEIdentityCheckRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s13/events/JMEIdentityCheckAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.api.s13.events; import org.jdiameter.api.app.AppAnswerEvent; @SuppressWarnings("all") //3rd party lib public interface JMEIdentityCheckAnswer extends AppAnswerEvent { String _SHORT_NAME = "ECA"; String _LONG_NAME = "ME-Identity-Check-Answer"; int code = 324; boolean isEquipmentStatusAVPPresent(); int getEquipmentStatus(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s13/events/JMEIdentityCheckRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.api.s13.events; import org.jdiameter.api.Avp; import org.jdiameter.api.app.AppRequestEvent; /** * The ECR command, indicated by the Command-Code field set to 324 and the 'R' bit set in the Command Flags field, is * sent by MME or SGSN to EIR to check the Mobile Equipment's identity status (e.g. to check that it has not been * stolen, or, to verify that it does not have faults). */ @SuppressWarnings("all") //3rd party lib public interface JMEIdentityCheckRequest extends AppRequestEvent { String _SHORT_NAME = "ECR"; String _LONG_NAME = "ME-Identity-Check-Request"; int code = 324; Avp getTerminalInformationAvp(); boolean hasIMEI(); String getIMEI(); boolean hasTgpp2MEID(); byte[] getTgpp2MEID(); boolean hasSoftwareVersion(); String getSoftwareVersion(); boolean isUserNameAVPPresent(); String getUserName(); } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/ClientS6aSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.s6a.events.JAuthenticationInformationRequest; import org.jdiameter.api.s6a.events.JCancelLocationAnswer; import org.jdiameter.api.s6a.events.JDeleteSubscriberDataAnswer; import org.jdiameter.api.s6a.events.JInsertSubscriberDataAnswer; import org.jdiameter.api.s6a.events.JNotifyRequest; import org.jdiameter.api.s6a.events.JPurgeUERequest; import org.jdiameter.api.s6a.events.JResetAnswer; import org.jdiameter.api.s6a.events.JUpdateLocationRequest; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientS6aSession extends AppSession, StateMachine { /** * Send Authentication-Information-Request to server * * @param request Authentication-Information-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendAuthenticationInformationRequest(JAuthenticationInformationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Purge-UE-Request to server * * @param request Purge-UE-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendPurgeUERequest(JPurgeUERequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Notify-Request to server * * @param request Notify-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendNotifyRequest(JNotifyRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Update-Location-Request to server * * @param request Update-Location-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendUpdateLocationRequest(JUpdateLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Cancel-Location-Answer to server * * @param answer Cancel-Location-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendCancelLocationAnswer(JCancelLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Insert-Subscriber-Data-Answer to server * * @param answer Insert-Subscriber-Data-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendInsertSubscriberDataAnswer(JInsertSubscriberDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Delete-Subscriber-Data-Answer to server * * @param answer Delete-Subscriber-Data-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendDeleteSubscriberDataAnswer(JDeleteSubscriberDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Reset-Answer to server * * @param answer Reset-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendResetAnswer(JResetAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/ClientS6aSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.s6a.events.JAuthenticationInformationAnswer; import org.jdiameter.api.s6a.events.JAuthenticationInformationRequest; import org.jdiameter.api.s6a.events.JCancelLocationRequest; import org.jdiameter.api.s6a.events.JDeleteSubscriberDataRequest; import org.jdiameter.api.s6a.events.JInsertSubscriberDataRequest; import org.jdiameter.api.s6a.events.JNotifyAnswer; import org.jdiameter.api.s6a.events.JNotifyRequest; import org.jdiameter.api.s6a.events.JPurgeUEAnswer; import org.jdiameter.api.s6a.events.JPurgeUERequest; import org.jdiameter.api.s6a.events.JResetRequest; import org.jdiameter.api.s6a.events.JUpdateLocationAnswer; import org.jdiameter.api.s6a.events.JUpdateLocationRequest; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ClientS6aSessionListener { void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doCancelLocationRequestEvent(ClientS6aSession session, JCancelLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doInsertSubscriberDataRequestEvent(ClientS6aSession session, JInsertSubscriberDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doDeleteSubscriberDataRequestEvent(ClientS6aSession session, JDeleteSubscriberDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doResetRequestEvent(ClientS6aSession session, JResetRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doAuthenticationInformationAnswerEvent(ClientS6aSession session, JAuthenticationInformationRequest request, JAuthenticationInformationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doPurgeUEAnswerEvent(ClientS6aSession session, JPurgeUERequest request, JPurgeUEAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doUpdateLocationAnswerEvent(ClientS6aSession session, JUpdateLocationRequest request, JUpdateLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doNotifyAnswerEvent(ClientS6aSession session, JNotifyRequest request, JNotifyAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/ServerS6aSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.s6a.events.JAuthenticationInformationAnswer; import org.jdiameter.api.s6a.events.JCancelLocationRequest; import org.jdiameter.api.s6a.events.JDeleteSubscriberDataRequest; import org.jdiameter.api.s6a.events.JInsertSubscriberDataRequest; import org.jdiameter.api.s6a.events.JNotifyAnswer; import org.jdiameter.api.s6a.events.JPurgeUEAnswer; import org.jdiameter.api.s6a.events.JResetRequest; import org.jdiameter.api.s6a.events.JUpdateLocationAnswer; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface ServerS6aSession extends AppSession, StateMachine { /** * Send Cancel-Location-Request to client * * @param request Cancel-Location-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendCancelLocationRequest(JCancelLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Insert-Subscriber-Data-Request to client * * @param request Insert-Subscriber-Data-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendInsertSubscriberDataRequest(JInsertSubscriberDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Delete-Subscriber-Data-Request to client * * @param request Delete-Subscriber-Data-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendDeleteSubscriberDataRequest(JDeleteSubscriberDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Reset-Request to client * * @param request Reset-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendResetRequest(JResetRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Authentication-Information-Answer to client * * @param answer Authentication-Information-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendAuthenticationInformationAnswer(JAuthenticationInformationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Purge-UE-Answer to client * * @param answer Purge-UE-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendPurgeUEAnswer(JPurgeUEAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Notify-Answer to client * * @param answer Notify-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendNotifyAnswer(JNotifyAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Update-Location-Answer to client * * @param answer Update-Location-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendUpdateLocationAnswer(JUpdateLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/ServerS6aSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.s6a.events.JAuthenticationInformationRequest; import org.jdiameter.api.s6a.events.JCancelLocationAnswer; import org.jdiameter.api.s6a.events.JCancelLocationRequest; import org.jdiameter.api.s6a.events.JDeleteSubscriberDataAnswer; import org.jdiameter.api.s6a.events.JDeleteSubscriberDataRequest; import org.jdiameter.api.s6a.events.JInsertSubscriberDataAnswer; import org.jdiameter.api.s6a.events.JInsertSubscriberDataRequest; import org.jdiameter.api.s6a.events.JNotifyRequest; import org.jdiameter.api.s6a.events.JPurgeUERequest; import org.jdiameter.api.s6a.events.JResetAnswer; import org.jdiameter.api.s6a.events.JResetRequest; import org.jdiameter.api.s6a.events.JUpdateLocationRequest; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface ServerS6aSessionListener { void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doAuthenticationInformationRequestEvent(ServerS6aSession session, JAuthenticationInformationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doPurgeUERequestEvent(ServerS6aSession session, JPurgeUERequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doUpdateLocationRequestEvent(ServerS6aSession session, JUpdateLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doNotifyRequestEvent(ServerS6aSession session, JNotifyRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doCancelLocationAnswerEvent(ServerS6aSession session, JCancelLocationRequest request, JCancelLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doInsertSubscriberDataAnswerEvent(ServerS6aSession session, JInsertSubscriberDataRequest request, JInsertSubscriberDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doDeleteSubscriberDataAnswerEvent(ServerS6aSession session, JDeleteSubscriberDataRequest request, JDeleteSubscriberDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doResetAnswerEvent(ServerS6aSession session, JResetRequest request, JResetAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JAuthenticationInformationAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface JAuthenticationInformationAnswer extends AppAnswerEvent { String _SHORT_NAME = "AIA"; String _LONG_NAME = "Authentication-Information-Answer"; int code = 318; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JAuthenticationInformationRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface JAuthenticationInformationRequest extends AppRequestEvent { String _SHORT_NAME = "AIR"; String _LONG_NAME = "Authentication-Information-Request"; int code = 318; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JCancelLocationAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JCancelLocationAnswer extends AppAnswerEvent { String _SHORT_NAME = "CLA"; String _LONG_NAME = "Cancel-Location-Answer"; int code = 317; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JCancelLocationRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JCancelLocationRequest extends AppRequestEvent { String _SHORT_NAME = "CLR"; String _LONG_NAME = "Cancel-Location-Request"; int code = 317; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JDeleteSubscriberDataAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JDeleteSubscriberDataAnswer extends AppAnswerEvent { String _SHORT_NAME = "DSA"; String _LONG_NAME = "Delete-Subscriber-Data-Answer"; int code = 320; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JDeleteSubscriberDataRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JDeleteSubscriberDataRequest extends AppRequestEvent { String _SHORT_NAME = "DSR"; String _LONG_NAME = "Delete-Subscriber-Data-Request"; int code = 320; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JInsertSubscriberDataAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JInsertSubscriberDataAnswer extends AppAnswerEvent { String _SHORT_NAME = "IDA"; String _LONG_NAME = "Insert-Subscriber-Data-Answer"; int code = 319; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JInsertSubscriberDataRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JInsertSubscriberDataRequest extends AppRequestEvent { String _SHORT_NAME = "IDR"; String _LONG_NAME = "Insert-Subscriber-Data-Request"; int code = 319; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JNotifyAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JNotifyAnswer extends AppAnswerEvent { String _SHORT_NAME = "NOA"; String _LONG_NAME = "Notify-Answer"; int code = 323; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JNotifyRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JNotifyRequest extends AppRequestEvent { String _SHORT_NAME = "NOR"; String _LONG_NAME = "Notify-Request"; int code = 323; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JPurgeUEAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface JPurgeUEAnswer extends AppAnswerEvent { String _SHORT_NAME = "PUA"; String _LONG_NAME = "Purge-UE-Answer"; int code = 321; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JPurgeUERequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface JPurgeUERequest extends AppRequestEvent { String _SHORT_NAME = "PUR"; String _LONG_NAME = "Purge-UE-Request"; int code = 321; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JResetAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JResetAnswer extends AppAnswerEvent { String _SHORT_NAME = "RSA"; String _LONG_NAME = "Reset-Answer"; int code = 322; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JResetRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface JResetRequest extends AppRequestEvent { String _SHORT_NAME = "RSR"; String _LONG_NAME = "Reset-Request"; int code = 322; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JUpdateLocationAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface JUpdateLocationAnswer extends AppAnswerEvent { String _SHORT_NAME = "ULA"; String _LONG_NAME = "Update-Location-Answer"; int code = 316; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/s6a/events/JUpdateLocationRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.s6a.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface JUpdateLocationRequest extends AppRequestEvent { String _SHORT_NAME = "ULR"; String _LONG_NAME = "Update-Location-Request"; int code = 316; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/ClientShSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.sh.events.ProfileUpdateRequest; import org.jdiameter.api.sh.events.PushNotificationAnswer; import org.jdiameter.api.sh.events.SubscribeNotificationsRequest; import org.jdiameter.api.sh.events.UserDataRequest; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ClientShSession extends AppSession, StateMachine { /** * Send profile update request to server * * @param request Authentication-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendProfileUpdateRequest(ProfileUpdateRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send subscription request to server * * @param request Authentication-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendSubscribeNotificationsRequest(SubscribeNotificationsRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send user data request to server * * @param request Authentication-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendUserDataRequest(UserDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void sendPushNotificationAnswer(PushNotificationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/ClientShSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.sh.events.ProfileUpdateAnswer; import org.jdiameter.api.sh.events.ProfileUpdateRequest; import org.jdiameter.api.sh.events.PushNotificationRequest; import org.jdiameter.api.sh.events.SubscribeNotificationsAnswer; import org.jdiameter.api.sh.events.SubscribeNotificationsRequest; import org.jdiameter.api.sh.events.UserDataAnswer; import org.jdiameter.api.sh.events.UserDataRequest; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ClientShSessionListener { void doSubscribeNotificationsAnswerEvent(ClientShSession session, SubscribeNotificationsRequest request, SubscribeNotificationsAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doProfileUpdateAnswerEvent(ClientShSession session, ProfileUpdateRequest request, ProfileUpdateAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doPushNotificationRequestEvent(ClientShSession session, PushNotificationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doUserDataAnswerEvent(ClientShSession session, UserDataRequest request, UserDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ShSessionEventListener that the ClientShSession has received not Sh message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/ServerShSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.sh.events.ProfileUpdateAnswer; import org.jdiameter.api.sh.events.PushNotificationRequest; import org.jdiameter.api.sh.events.SubscribeNotificationsAnswer; import org.jdiameter.api.sh.events.UserDataAnswer; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ServerShSession extends AppSession, StateMachine { /** * Send profile update notification request to client * * @param request Authentication-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendPushNotificationRequest(PushNotificationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send profile update answer to client * * @param request Authentication-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendProfileUpdateAnswer(ProfileUpdateAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send subscribe notification answer to client * * @param request Authentication-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendSubscribeNotificationsAnswer(SubscribeNotificationsAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send user data answer to client * * @param request Authentication-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. **/ void sendUserDataAnswer(UserDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/ServerShSessionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.sh.events.ProfileUpdateRequest; import org.jdiameter.api.sh.events.PushNotificationAnswer; import org.jdiameter.api.sh.events.PushNotificationRequest; import org.jdiameter.api.sh.events.SubscribeNotificationsRequest; import org.jdiameter.api.sh.events.UserDataRequest; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ServerShSessionListener { void doSubscribeNotificationsRequestEvent(ServerShSession session, SubscribeNotificationsRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doProfileUpdateRequestEvent(ServerShSession session, ProfileUpdateRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doPushNotificationAnswerEvent(ServerShSession session, PushNotificationRequest request, PushNotificationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doUserDataRequestEvent(ServerShSession session, UserDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Notifies this ShSessionEventListener that the ServerShSession has received not Sh message. * * @param session parent application session (FSM) * @param request request object * @param answer answer object * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/events/ProfileUpdateAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The Profile-Update-Answer (PUA) command, indicated by the Command-Code field set to 307 and the bit cleared in the * Command Flags field, is sent by a server in response to the Profile-Update-Request command. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ProfileUpdateAnswer extends AppAnswerEvent { String _SHORT_NAME = "PUA"; String _LONG_NAME = "Profile-Update-Answer"; int code = 307; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/events/ProfileUpdateRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh.events; import org.jdiameter.api.app.AppRequestEvent; /** * The Profile-Update-Request (PUR) command, indicated by the Command-Code field set to 307 and the bit set in the * Command Flags field, is sent by a Diameter client to a Diameter server in order to update user data in the server. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ProfileUpdateRequest extends AppRequestEvent { String _SHORT_NAME = "PUR"; String _LONG_NAME = "Profile-Update-Request"; int code = 307; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/events/PushNotificationAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The Push-Notifications-Answer (PNA) command, indicated by the Command-Code field set to 309 and the bit cleared in * the Command Flags field, is sent by a client in response to the Push-Notification-Request command. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface PushNotificationAnswer extends AppAnswerEvent { String _SHORT_NAME = "PNA"; String _LONG_NAME = "Push-Notification-Answer"; int code = 309; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/events/PushNotificationRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh.events; import org.jdiameter.api.app.AppRequestEvent; /** * The Push-Notification-Request (PNR) command, indicated by the Command-Code field set to 309 and the bit set in the * Command Flags field, is sent by a Diameter server to a Diameter client in order to notify changes in the user data in * the server. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface PushNotificationRequest extends AppRequestEvent { String _SHORT_NAME = "PNR"; String _LONG_NAME = "Push-Notification-Request"; int code = 309; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/events/SubscribeNotificationsAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The Subscribe-Notifications-Answer command, indicated by the Command-Code field set to 308 and the bit cleared in the * Command Flags field, is sent by a server in response to the Subscribe-Notifications-Request command. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface SubscribeNotificationsAnswer extends AppAnswerEvent { String _SHORT_NAME = "SNA"; String _LONG_NAME = "Subscribe-Notifications-Answer"; int code = 308; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/events/SubscribeNotificationsRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh.events; import org.jdiameter.api.app.AppRequestEvent; /** * The Subscribe-Notifications-Request (SNR) command, indicated by the Command-Code field set to 308 and the bit set in * the Command Flags field, is sent by a Diameter client to a Diameter server in order to request notifications of * changes in user data. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface SubscribeNotificationsRequest extends AppRequestEvent { String _SHORT_NAME = "SNR"; String _LONG_NAME = "Subscribe-Notifications-Request"; int code = 308; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/events/UserDataAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh.events; import org.jdiameter.api.app.AppAnswerEvent; /** * The User-Data-Answer (UDA) command, indicated by the Command-Code field set to 306 and the bit cleared in the Command * Flags field, is sent by a server in response to the User-Data-Request command. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface UserDataAnswer extends AppAnswerEvent { String _SHORT_NAME = "UDA"; String _LONG_NAME = "User-Data-Answer"; int code = 306; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/sh/events/UserDataRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.sh.events; import org.jdiameter.api.app.AppRequestEvent; /** * The User-Data-Request (UDR) command, indicated by the Command-Code field set to 306 and the bit set in the Command * Flags field, is sent by a Diameter client to a Diameter server in order to request user data. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface UserDataRequest extends AppRequestEvent { String _SHORT_NAME = "UDR"; String _LONG_NAME = "User-Data-Request"; int code = 306; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ClientSLgSession.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slg; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.slg.events.LocationReportAnswer; import org.jdiameter.api.slg.events.ProvideLocationRequest; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ClientSLgSession extends AppSession, StateMachine { /** * Send Provide-Location-Request to server * * @param request Provide-Location-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendProvideLocationRequest(ProvideLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Location-Report-Answer to server * * @param answer Location-Report-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendLocationReportAnswer(LocationReportAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ClientSLgSessionListener.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slg; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.slg.events.LocationReportRequest; import org.jdiameter.api.slg.events.ProvideLocationAnswer; import org.jdiameter.api.slg.events.ProvideLocationRequest; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ClientSLgSessionListener { void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doProvideLocationAnswerEvent(ClientSLgSession session, ProvideLocationRequest request, ProvideLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doLocationReportRequestEvent(ClientSLgSession session, LocationReportRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ServerSLgSession.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slg; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.slg.events.LocationReportRequest; import org.jdiameter.api.slg.events.ProvideLocationAnswer; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ServerSLgSession extends AppSession, StateMachine { /** * Send Provide-Location-Answer to client * * @param answer Provide-Location-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendProvideLocationAnswer(ProvideLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; /** * Send Location-Report-Request to client * * @param request Location-Report-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendLocationReportRequest(LocationReportRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ServerSLgSessionListener.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slg; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.slg.events.LocationReportAnswer; import org.jdiameter.api.slg.events.LocationReportRequest; import org.jdiameter.api.slg.events.ProvideLocationRequest; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ServerSLgSessionListener { void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doProvideLocationRequestEvent(ServerSLgSession session, ProvideLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doLocationReportAnswerEvent(ServerSLgSession session, LocationReportRequest request, LocationReportAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/LocationReportAnswer.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slg.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Fernando Mendioroz */ /* * As for 3GPP TS 29.172 v13.0.0, Subscriber Location Report operation is used by an MME or SGSN to provide the location of a * target UE to a GMLC, when a request for location has been implicitly issued or when a Delayed Location Reporting is triggered * after receipt of a request for location for a UE transiently not reachable. * * The Location-Report-Answer (LRA) command, indicated by the Command-Code field set to 8388621 and the "R" bit cleared in the * Command Flags field, is sent by the GMLC to the MME or SGSN in response to the Location-Report-Request command (Subscriber * Location Report operation answer). */ @SuppressWarnings("all") //3rd party lib public interface LocationReportAnswer extends AppAnswerEvent { String _SHORT_NAME = "LRA"; String _LONG_NAME = "Location-Report-Answer"; int code = 8388621; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/LocationReportRequest.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slg.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Fernando Mendioroz */ /* * As for 3GPP TS 29.172 v13.0.0, Subscriber Location Report operation is used by an MME or SGSN to provide the location of a * target UE to a GMLC, when a request for location has been implicitly issued or when a Delayed Location Reporting is triggered * after receipt of a request for location for a UE transiently not reachable. * * The Location-Report-Request (LRR) command, indicated by the Command-Code field set to 8388621 and the "R" bit set in the * Command Flags field, is sent by the MME or SGSN in order to provide subscriber location data to the GMLC (Subscriber Location * Report operation request) */ @SuppressWarnings("all") //3rd party lib public interface LocationReportRequest extends AppRequestEvent { String _SHORT_NAME = "LRR"; String _LONG_NAME = "Location-Report-Request"; int code = 8388621; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/ProvideLocationAnswer.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slg.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Fernando Mendioroz */ /* * As for 3GPP TS 29.172 v13.0.0, the Provide Subscriber Location operation is used by a GMLC to request the location of a * target UE from the MME or SGSN at any time, as part of EPC-MT-LR (Evolved Packet Core Mobile Terminated Location Request) or * PS-MT-LR (Packet Switched Mobile Terminated Location Request) positioning procedures. The response contains a location * estimate of the target UE and other additional information. This operation is also used by a GMLC to request the location of * the target UE from the SGSN at any time, as part of deferred MT-LR procedure. The response contains the acknowledgment of the * receipt of the request and other additional information. * * The Provide-Location-Answer (PLA) command, indicated by the Command-Code field set to 8388620 and the "R" bit cleared in the * Command Flags field, is sent by the MME or SGSN to the GMLC in response to the Provide-Location-Request command (Provide * Subscriber Location operation answer) */ @SuppressWarnings("all") //3rd party lib public interface ProvideLocationAnswer extends AppAnswerEvent { String _SHORT_NAME = "PLA"; String _LONG_NAME = "Provide-Location-Answer"; int code = 8388620; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/ProvideLocationRequest.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slg.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Fernando Mendioroz */ /* * As for 3GPP TS 29.172 v13.0.0, the Provide Subscriber Location operation is used by a GMLC to request the location of a * target UE from the MME or SGSN at any time, as part of EPC-MT-LR (Evolved Packet Core Mobile Terminated Location Request) or * PS-MT-LR (Packet Switched Mobile Terminated Location Request) positioning procedures. The response contains a location * estimate of the target UE and other additional information. This operation is also used by a GMLC to request the location of * the target UE from the SGSN at any time, as part of deferred MT-LR procedure. The response contains the acknowledgment of the * receipt of the request and other additional information. * * The Provide-Location-Request (PLR) command, indicated by the Command-Code field set to 8388620 and the "R" bit set in the * Command Flags field, is sent by the GMLC in order to request subscriber location to the MME or SGSN (Provide Subscriber * Location operation request) */ @SuppressWarnings("all") //3rd party lib public interface ProvideLocationRequest extends AppRequestEvent { String _SHORT_NAME = "PLR"; String _LONG_NAME = "Provide-Location-Request"; int code = 8388620; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ClientSLhSession.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slh; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ClientSLhSession extends AppSession, StateMachine { /** * Send LCS-Routing-Info-Request to server * * @param request LCS-Routing-Info-Request event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendLCSRoutingInfoRequest(LCSRoutingInfoRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ClientSLhSessionListener.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slh; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ClientSLhSessionListener { void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doLCSRoutingInfoAnswerEvent(ClientSLhSession session, LCSRoutingInfoRequest request, LCSRoutingInfoAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ServerSLhSession.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slh; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateMachine; import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ServerSLhSession extends AppSession, StateMachine { /** * Send LCS-Routing-Info-Answer to client * * @param answer LCS-Routing-Info-Answer event instance * * @throws InternalException The InternalException signals that internal error is occurred. * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state * (invalid). * @throws RouteException The NoRouteException signals that no route exist for a given realm. * @throws OverloadException The OverloadException signals that destination host is overloaded. */ void sendLCSRoutingInfoAnswer(LCSRoutingInfoAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ServerSLhSessionListener.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slh; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ServerSLhSessionListener { void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void doLCSRoutingInfoRequestEvent(ServerSLhSession session, LCSRoutingInfoRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slh/events/LCSRoutingInfoAnswer.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slh.events; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Fernando Mendioroz */ /* * As for 3GPP TS 29.173 v13.0.0, the LCS-Routing-Info-Answer (RIA) command, indicated by the Command-Code field set to 8388622 * and the "R" bit cleared in the Command Flags field, is sent from HSS to GMLC. The procedure invoked by the GMLC is used for * retrieving routing information for LCS (Location Services) for a specified user from the HSS via a LCS-Routing-Info-Request * (RIR) command. * */ @SuppressWarnings("all") //3rd party lib public interface LCSRoutingInfoAnswer extends AppAnswerEvent { String _SHORT_NAME = "RIA"; String _LONG_NAME = "LCS-Routing-Info-Answer"; int code = 8388622; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/slh/events/LCSRoutingInfoRequest.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.api.slh.events; import org.jdiameter.api.app.AppRequestEvent; /** * @author Fernando Mendioroz */ /* * As for 3GPP TS 29.173 v13.0.0, the LCS-Routing-Info-Request (RIR) command, indicated by the Command-Code field set to 8388622 * and the "R" bit set in the Command Flags field, is sent from GMLC to HSS. The procedure invoked by the GMLC is used for * retrieving routing information for LCS (Location Services) for a specified user from the HSS. * */ @SuppressWarnings("all") //3rd party lib public interface LCSRoutingInfoRequest extends AppRequestEvent { String _SHORT_NAME = "RIR"; String _LONG_NAME = "LCS-Routing-Info-Request"; int code = 8388622; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/validation/AvpNotAllowedException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.validation; /** * Class to indicate error in AVP add operation. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AvpNotAllowedException extends RuntimeException { private static final long serialVersionUID = 1L; private int avpCode = -1; private long vendorId = -1L; /** * */ public AvpNotAllowedException(int code, long vendor) { this.avpCode = code; this.vendorId = vendor; } /** * @param message */ public AvpNotAllowedException(String message, int code, long vendor) { super(message); this.avpCode = code; this.vendorId = vendor; } /** * @param cause */ public AvpNotAllowedException(Throwable cause, int code, long vendor) { super(cause); this.avpCode = code; this.vendorId = vendor; } /** * @param message * @param cause */ public AvpNotAllowedException(String message, Throwable cause, int code, long vendor) { super(message, cause); this.avpCode = code; this.vendorId = vendor; } public int getAvpCode() { return avpCode; } public long getVendorId() { return vendorId; } @Override public String toString() { return "AvpNotAllowedException [avpCode=" + avpCode + ", vendorId=" + vendorId + ", toString()=" + super.toString() + "]"; } } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/validation/AvpRepresentation.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.validation; import java.util.List; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpSet; /** * Represents avp, it stores info about presence, multiplicity, avp code, vendor. * * @author Bartosz Baranowski * @author Alexandre Mendonca * @since 1.5.4.0-build404 */ @SuppressWarnings("all") //3rd party lib public interface AvpRepresentation { /** *

           * Represents multiplicity of AVP:
           * 0     The AVP MUST NOT be present in the message.
           * 
      */ String _MP_NOT_ALLOWED = "0"; /** *
           * Represents multiplicity of AVP:
           * 0+    Zero or more instances of the AVP MAY be present in the message.
           * 
      */ String _MP_ZERO_OR_MORE = "0+"; /** *
           * Represents multiplicity of AVP:
           * 0-1   Zero or one instance of the AVP MAY be present in the message.
           *       It is considered an error if there are more than one instance of the AVP.
           * 
      */ String _MP_ZERO_OR_ONE = "0-1"; /** *
           * Represents multiplicity of AVP:
           * 1     One instance of the AVP MUST be present in the message.
           *       message.
           * 
      */ String _MP_ONE = "1"; /** *
           * Represents multiplicity of AVP:
           * 1+    At least one instance of the AVP MUST be present in the
           *       message.
           * 
      */ String _MP_ONE_AND_MORE = "1+"; String _DEFAULT_MANDATORY = "may"; String _DEFAULT_PROTECTED = "may"; String _DEFAULT_VENDOR = "mustnot"; int _FIX_POSITION_INDEX = -1; enum Rule { must, may, mustnot, shouldnot } ; enum Type { OctetString, Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64, Grouped, Address, Time, UTF8String, DiameterIdentity, DiameterURI, Enumerated, IPFilterRule, QoSFilterRule } ; boolean isPositionFixed(); //public void markFixPosition(int index); boolean isCountValidForMultiplicity(int avpCount); boolean isCountValidForMultiplicity(AvpSet destination, int numberToAdd); boolean isAllowed(int avpCode, long vendorId); boolean isAllowed(int avpCode); int getPositionIndex(); int getCode(); long getVendorId(); boolean isAllowed(); String getMultiplicityIndicator(); String getName(); boolean isGrouped(); //public void setGrouped(boolean grouped); List getChildren(); //public void setChildren(List children); //public void setCode(int code); //public void setVendorId(long vendor); //public void setMultiplicityIndicator(String multiplicityIndicator); //public void setName(String name); boolean isWeak(); //public void markWeak(boolean isWeak); String getDescription(); boolean isMayEncrypt(); String getRuleMandatory(); int getRuleMandatoryAsInt(); String getRuleProtected(); int getRuleProtectedAsInt(); String getRuleVendorBit(); int getRuleVendorBitAsInt(); String getOriginalType(); String getType(); boolean isProtected(); boolean isMandatory(); /** * Validates passed avp. * * @param avp - simply avp which should be confronted vs definition */ void validate(Avp avp) throws AvpNotAllowedException; /** * Validates passed avp. * * @param avpSet - AvpSet which represents internal content of this avp */ void validate(AvpSet avpSet) throws AvpNotAllowedException; @Override String toString(); @Override int hashCode(); @Override boolean equals(Object obj); Object clone() throws CloneNotSupportedException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/validation/Dictionary.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.validation; import java.io.InputStream; import org.jdiameter.api.Message; /** * Second generation Dictionary/Validator. This interface is exposed directly. * * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.1 */ @SuppressWarnings("all") //3rd party lib public interface Dictionary { /** * Fetches Avp representation for given code. If no such AVP is found, * null value is returned. * * @param code - positive integer, equal to AVP code. * * @return AvpRepresentation for given code or null */ AvpRepresentation getAvp(int code); /** * Fetches Avp representation for given code and vendorId. If no such AVP is found, null value is returned. * * @param code - positive integer, equal to AVP code. * @param vendorId - positive long representing vendor code. * * @return AvpRepresentation for given code/vendor pair or null */ AvpRepresentation getAvp(int code, long vendorId); /** * Fetches Avp representation for given name. If no such AVP is found, * null value is returned. * * @param name - name of AVP, like Session-Id. * * @return AvpRepresentation for given name or null */ AvpRepresentation getAvp(String avpName); /** * @param commandCode - command code of message * @param isRequest - switches if lookup searches for request or answer * * @return message representation for given code and flag value or * null */ MessageRepresentation getMessage(int commandCode, boolean isRequest); /** * @param commandCode - command code of message * @param applicationId - application id present in message header * @param isRequest - switches if lookup searches for request or answer * * @return message representation for given code, application and flag value or null */ MessageRepresentation getMessage(int commandCode, long applicationId, boolean isRequest); /** * Configures dictionary. It can be called multiple times, each call reconfigures dictionary. * * @param is */ void configure(InputStream is); // Validator ---------------------------------------------------------------- /** * Gets whether validator is enabled. * * @return *
        *
      • true if validator is enabled
      • *
      • false if validator is disabled
      • *
      */ boolean isEnabled(); /** * Sets whether validator is enabled. * * @param enabled true to enable the validator, false to disable it */ void setEnabled(boolean enabled); /** * Gets whether validator is configured. * * @return *
        *
      • true if validator has been initialized
      • *
      • false if validator has not yet been initialized
      • *
      */ boolean isConfigured(); /** * Gets validator level for OUTGOING messages. Possible values are defined at {@link ValidatorLevel} * * @return an instance of {@link ValidatorLevel} representing the current level */ ValidatorLevel getSendLevel(); /** * Gets validator level for OUTGOING messages. Possible values are defined at {@link ValidatorLevel} * * @param sendLevel an instance of {@link ValidatorLevel} representing the new level */ void setSendLevel(ValidatorLevel sendLevel); /** * Gets validator level for INCOMING messages. Possible values are defined at {@link ValidatorLevel} * * @return an instance of {@link ValidatorLevel} representing the current level */ ValidatorLevel getReceiveLevel(); /** * Sets validator level for INCOMING messages. Possible values are defined at {@link ValidatorLevel} * * @param receiveLevel an instance of {@link ValidatorLevel} representing the new level */ void setReceiveLevel(ValidatorLevel receiveLevel); /** * Performs validation according to configured levels * * @param message - message we want to validate * @param incoming - flag indicating if {@link #message} is incoming message or outgoing. * * @throws AvpNotAllowedException - in case validation fails. Exception has details(avp code and similar) about * failure. */ void validate(Message message, boolean incoming) throws AvpNotAllowedException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/validation/MessageRepresentation.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.validation; import java.util.Map; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Message; /** * This class represents message/command in validation framework. It contains basic info about command along with avp * list - their multiplicity and allowance. * * @author Bartosz Baranowski * @author Alexandre Mendonca * @since 1.5.4.0-build404 */ @SuppressWarnings("all") //3rd party lib public interface MessageRepresentation { Map getMessageAvps(); int getCommandCode(); long getApplicationId(); boolean isRequest(); String getName(); /** * Fetches Avp representation for given code. If no such AVP is found, * null value is returned. AVP must be top level AVP to be fetched by * this operation. * * @param code - positive integer, equal to AVP code. * * @return AvpRepresentation for given code or null */ AvpRepresentation getAvp(int code); /** * Fetches Avp representation for given code and vendorId. If no such AVP is found, null value is returned. * AVP must be top level AVP to be fetched by this operation. * * @param code - positive integer, equal to AVP code. * @param vendorId - positive long representing vendor code. * * @return AvpRepresentation for given code/vendor pair or null */ AvpRepresentation getAvp(int code, long vendorId); boolean isCountValidForMultiplicity(int code, int avpCount); boolean isCountValidForMultiplicity(int code, long vendorId, int avpCount); boolean isCountValidForMultiplicity(AvpSet destination, int code, long vendorId, int numberToAdd); boolean isCountValidForMultiplicity(AvpSet destination, int code, int numberToAdd); boolean isCountValidForMultiplicity(AvpSet destination, int code, long vendorId); boolean isCountValidForMultiplicity(AvpSet destination, int code); boolean isAllowed(int avpCode, long vendorId); boolean isAllowed(int avpCode); void validate(Message msg, ValidatorLevel validatorLevel) throws AvpNotAllowedException; } ================================================ FILE: core/jdiameter/api/src/main/java/org/jdiameter/api/validation/ValidatorLevel.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.api.validation; /** * Represents possible levels for Diameter Validator * * @author Bartosz Baranowski * @author Alexandre Mendonca * @since 1.5.4.0-build404 */ @SuppressWarnings("all") //3rd party lib public class ValidatorLevel { public static final String _OFF = "OFF"; public static final String _MESSAGE = "MESSAGE"; public static final String _ALL = "ALL"; public static final ValidatorLevel OFF = new ValidatorLevel(_OFF); public static final ValidatorLevel MESSAGE = new ValidatorLevel(_MESSAGE); public static final ValidatorLevel ALL = new ValidatorLevel(_ALL); private String name = null; private ValidatorLevel(String name) { super(); this.name = name; } public static ValidatorLevel fromString(String s) throws IllegalArgumentException { if (s.toUpperCase().equals(_OFF)) { return OFF; } if (s.toUpperCase().equals(_MESSAGE)) { return MESSAGE; } if (s.toUpperCase().equals(_ALL)) { return ALL; } throw new IllegalArgumentException("No level for such value: " + s); } @Override public String toString() { return "ValidatorLevel [name=" + name + "]"; } } ================================================ FILE: core/jdiameter/impl/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter jdiameter-core 2.5.1-SNAPSHOT ../pom.xml jdiameter-impl Quarkus :: JDiameter Stack :: Impl Quarkus io.quarkiverse.jdiameter jdiameter-api org.slf4j slf4j-api ${slf4j.version} org.slf4j slf4j-ext ${slf4j.version} commons-pool commons-pool ${commons-pool.version} io.netty netty-all ${netty.version} provided org.junit.jupiter junit-jupiter-engine test ${junit.version} org.junit.jupiter junit-jupiter-api test ${junit.version} org.junit.jupiter junit-jupiter ${junit.version} test src/main/resources true ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IAnswer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; import org.jdiameter.api.Answer; /** * This interface describe extends methods of base class Now is empty Data: $Date: 2008/07/03 19:43:10 $ Revision: * $Revision: 1.1 $ * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ @SuppressWarnings("all") //3rd party lib public interface IAnswer extends Answer { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IAssembler.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; /** * This interface provide IOC functionality Data: $Date: 2009/10/10 20:17:57 $ Revision: $Revision: 1.2 $ * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ @SuppressWarnings("all") //3rd party lib public interface IAssembler { /** * Return parent IOC * * @return IOC instance */ IAssembler getParent(); /** * Return all children * * @return all children */ IAssembler[] getChilds(); /** * Register new component * * @param aClass class of component * * @return instance of component */ T getComponentInstance(Class aClass); /** * Register new component * * @param object instance of component */ void registerComponentInstance(Object object); /** * Register new component * * @param aClass class of component * @param object instance of component */ void registerComponentImplementation(Class aClass, Object object); /** * Release all attached resources */ void destroy(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IContainer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; import java.io.IOException; import java.util.concurrent.ScheduledExecutorService; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Configuration; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.RouteException; import org.jdiameter.api.Stack; import org.jdiameter.common.api.concurrent.IConcurrentFactory; /** * This interface extends behavior of stack interface Data: $Date: 2008/07/03 19:43:10 $ Revision: $Revision: 1.1 $ * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ @SuppressWarnings("all") //3rd party lib public interface IContainer extends Stack { /** * Return state of stack * * @return Return state of stack */ StackState getState(); /** * Return configuration instance * * @return configuration instance */ Configuration getConfiguration(); /** * Return root IOC * * @return root IOC */ IAssembler getAssemblerFacility(); /** * Return common Scheduled Executor Service * * @return common Scheduled Executor Service */ ScheduledExecutorService getScheduledFacility(); /** * Return common concurrent factory * * @return */ IConcurrentFactory getConcurrentFactory(); /** * Send message * * @param session session instance * * @throws RouteException * @throws AvpDataException * @throws IllegalDiameterStateException * @throws IOException */ void sendMessage(IMessage session) throws RouteException, AvpDataException, IllegalDiameterStateException, IOException; /** * Add session listener * * @param sessionId session id * @param listener listener instance */ void addSessionListener(String sessionId, NetworkReqListener listener); /** * Remove session event listener by sessionId * * @param sessionId session identifier */ void removeSessionListener(String sessionId); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IEventListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.Request; /** * This interface describe extends methods of base class Data: $Date: 2008/07/03 19:43:10 $ Revision: $Revision: 1.1 $ * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ @SuppressWarnings("all") //3rd party lib public interface IEventListener extends EventListener { /** * Set value of valid field * * @param value true is listener yet valid */ void setValid(boolean value); /** * Return rue if event listener valid(session is not released) * * @return rue if event listener valid */ boolean isValid(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMessage.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.jdiameter.api.ApplicationId; import org.jdiameter.client.api.controller.IPeer; /** * This interface extends basic message interface Data: $Date: 2009/07/27 18:05:03 $ Revision: $Revision: 1.2 $ * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ @SuppressWarnings("all") //3rd party lib public interface IMessage extends IRequest, IAnswer { /** * The message is not sent to the network */ int STATE_NOT_SENT = 0; /** * The message has been sent to the network */ int STATE_SENT = 1; /** * The message is buffered ( not use yet ) */ int STATE_BUFFERED = 2; /** * Stack received answer to this message */ int STATE_ANSWERED = 3; /** * Return state of message * * @return state of message */ int getState(); /** * Set new state * * @param newState new state value */ void setState(int newState); /** * Return header applicationId * * @return header applicationId */ long getHeaderApplicationId(); /** * Set header message application id * * @param applicationId header message application id */ void setHeaderApplicationId(long applicationId); /** * Return flags as inteher * * @return flags as inteher */ int getFlags(); /** * Create timer for request timout procedure * * @param scheduledFacility timer facility * @param timeOut value of timeout * @param timeUnit time unit */ void createTimer(ScheduledExecutorService scheduledFacility, long timeOut, TimeUnit timeUnit); /** * Execute timer task */ void runTimer(); /** * Cancel timer */ void clearTimer(); /** * Set hop by hop id * * @param hopByHopId hopByHopId value */ void setHopByHopIdentifier(long hopByHopId); /** * Set end by end id * * @param endByEndId endByEndId value */ void setEndToEndIdentifier(long endByEndId); /** * Return attached peer * * @return attached peer */ IPeer getPeer(); /** * Attach message to peer * * @param peer attached peer */ void setPeer(IPeer peer); /** * Return application id * * @return application id */ ApplicationId getSingleApplicationId(); /** * Return application id * * @return application id */ ApplicationId getSingleApplicationId(long id); /** * Check timeout * * @return true if request has timeout */ boolean isTimeOut(); /** * Set event listener * * @param listener event listener */ void setListener(IEventListener listener); /** * Return event listener * * @return event listener */ IEventListener getEventListener(); /** * Return duplication key of message * * @return duplication key of message */ String getDuplicationKey(); /** * Generate duplication key * * @param host origination host * @param endToEndId end to end id * * @return duplication key */ String getDuplicationKey(String host, long endToEndId); /** * Create clone object * * @return clone */ Object clone(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IMetaData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; import org.jdiameter.api.MetaData; /** * This interface describe extends methods of base class Data: $Date: 2008/07/03 19:43:10 $ Revision: $Revision: 1.1 $ * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ @SuppressWarnings("all") //3rd party lib public interface IMetaData extends MetaData { /** * Set new value of host state */ void updateLocalHostStateId(); /** * Return host state value * * @return host state value */ long getLocalHostStateId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/IRequest.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; import org.jdiameter.api.Request; /** * This interface describe extends methods of base class Data: $Date: 2008/07/03 19:43:10 $ Revision: $Revision: 1.1 $ * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ @SuppressWarnings("all") //3rd party lib public interface IRequest extends Request { /** * Set network request flag * * @param isNetwork true if this request is neteork */ void setNetworkRequest(boolean isNetwork); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/ISession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.Session; /** * This interface describe extends methods of base class Data: $Date: 2009/07/27 18:05:03 $ Revision: $Revision: 1.3 $ * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ @SuppressWarnings("all") //3rd party lib public interface ISession extends Session { NetworkReqListener getReqListener(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/ISessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.InternalException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppSession; import org.jdiameter.common.api.app.IAppSessionFactory; /** * This interface describe extends methods of base class * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ @SuppressWarnings("all") //3rd party lib public interface ISessionFactory extends SessionFactory { /** * Method used for creating a new App Session using the specified class with the desired Application Id and Session * Id. * * @param sessionId the session-id for this App Session, if desired * @param applicationId the application id for this session * @param aClass the class of the app session object * @param args * * @return an AppSession instance * * @throws InternalException */ T getNewAppSession(String sessionId, ApplicationId applicationId, Class aClass, Object... args) throws InternalException; /** * Registers a new App Session factory. * * @param sessionClass the class of the objects being generated by the factory * @param factory the factory to generate app sessions */ void registerAppFacory(Class sessionClass, IAppSessionFactory factory); /** * Unregisters an existing App Session factory. * * @param sessionClass the class identifier for this factory */ void unRegisterAppFacory(Class sessionClass); /** * Retrieves the app session factory associated with an app session class * * @param sessionClass the class identifier for the desired factory * * @return the App Session Factory instance if registered, null if no factory is registered for such class */ IAppSessionFactory getAppSessionFactory(Class sessionClass); /** * @return */ IContainer getContainer(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/StackState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api; /** * This enumeration describe avaliable states of stack Data: $Date: 2008/07/03 19:43:10 $ Revision: $Revision: 1.1 $ * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @version 1.5.0.1 */ public enum StackState { IDLE, CONFIGURED, STARTED, STOPPED } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/annotation/IRecoder.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.annotation; import org.jdiameter.api.Avp; import org.jdiameter.api.Message; import org.jdiameter.api.Request; /** * This interface provide methods for create diameter messages from your annotated domain object and create domain * object from diameter message. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IRecoder { /** * Create Request message from specified annotated domain object * * @param yourDomainMessageObject annotated domain object * @param additionalAvp additional avp * * @return message instance * * @throws RecoderException throw if object can not be encoded to diameter message */ Message encodeToRequest(Object yourDomainMessageObject, Avp... additionalAvp) throws RecoderException; /** * Create Answer message from specified annotated domain object * * @param yourDomainMessageObject annotated domain object * @param request request message * @param resultCode result code of answer * * @return message answer instance * * @throws RecoderException throw if object can not be encoded to diameter message */ Message encodeToAnswer(Object yourDomainMessageObject, Request request, long resultCode) throws RecoderException; /** * Create specified domain object by message and class of object * * @param message diameter message * @param yourDomainMessageObject class of domain object * * @return instance of domain object * * @throws RecoderException throw if message can not be decoded to domain object */ T decode(Message message, java.lang.Class yourDomainMessageObject) throws RecoderException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/annotation/RecoderException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.annotation; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RecoderException extends RuntimeException { private static final long serialVersionUID = 1L; public RecoderException(Throwable cause) { super(cause); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/controller/IPeer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.controller; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Peer; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.fsm.EventTypes; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.common.api.statistic.IStatistic; /** * This interface provide additional methods for Peer interface * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IPeer extends Peer { /** * Return rating of peer * * @return int value */ int getRating(); /** * Return new hop by hop id for new message * * @return new hop by hop id */ long getHopByHopIdentifier(); /** * Append request to peer request storage map * * @param message request instance */ void addMessage(IMessage message); /** * Remove request from request storage map * * @param message request instance */ void remMessage(IMessage message); /** * Clear request storage map */ IMessage[] remAllMessage(); /** * Put message to peer fsm * * @param message request instance * * @return true if message will be set to FSM * * @throws TransportException * @throws OverloadException */ boolean handleMessage(EventTypes type, IMessage message, String key) throws TransportException, OverloadException, InternalException; /** * Send message to diameter network * * @param message request instance * * @return true if message will be set to FSM * * @throws TransportException * @throws OverloadException */ boolean sendMessage(IMessage message) throws TransportException, OverloadException, InternalException; /** * Return true if peer has valid connection * * @return true if peer has valid connection */ boolean hasValidConnection(); /** * Attach peer to realm * * @param realm realm name */ void setRealm(String realm); /** * Add state change listener * * @param listener listener instance */ void addStateChangeListener(StateChangeListener listener); /** * Remove state change listener * * @param listener listener instance */ void remStateChangeListener(StateChangeListener listener); /** * Add connection state change listener * * @param listener listener instance */ void addConnectionListener(IConnectionListener listener); /** * Remove connection state change listener * * @param listener listener instance */ void remConnectionListener(IConnectionListener listener); /** * Return peer statistic * * @return peer statistic */ IStatistic getStatistic(); /** * Return if peer is connected * * @return is peer connected */ boolean isConnected(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/controller/IPeerTable.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.controller; import java.io.IOException; import java.util.Map; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.PeerTable; import org.jdiameter.api.RouteException; import org.jdiameter.client.api.IAssembler; import org.jdiameter.client.api.IMessage; /** * This interface provide additional methods for PeerTable interface * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IPeerTable extends PeerTable { /** * Start peer manager ( start network activity ) * * @throws IllegalDiameterStateException * @throws IOException */ void start() throws IllegalDiameterStateException, IOException; /** * Run stopping procedure (unsynchronized) */ void stopping(int disconnectCause); /** * Release resources */ void stopped(); /** * Destroy all resources */ void destroy(); /** * Send message to diameter network ( routing procedure ) * * @param message message instance * * @throws IllegalDiameterStateException * @throws IOException * @throws RouteException * @throws AvpDataException */ void sendMessage(IMessage message) throws IllegalDiameterStateException, IOException, RouteException, AvpDataException; /** * Register session lister * * @param sessionId session id * @param listener listener listener */ void addSessionReqListener(String sessionId, NetworkReqListener listener); /** * Return peer from peer table by identity - FQDN host name. * * @param fqdn peer host * * @return peer instance */ @Override IPeer getPeer(String fqdn); /** * Return map of session event listeners * * @return map of session event listeners */ Map getSessionReqListeners(); /** * Remove session event listener * * @param sessionId id of session */ void removeSessionListener(String sessionId); /** * Set instance assembler * * @param assembler assembler instance */ void setAssembler(IAssembler assembler); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/controller/IRealm.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.controller; import org.jdiameter.api.Realm; import org.jdiameter.server.api.agent.IAgent; import org.jdiameter.server.api.agent.IAgentConfiguration; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IRealm extends Realm { /** * Return list of real peers * * @return array of realm peers */ String[] getPeerNames(); /** * Append new host (peer) to this realm * * @param host name of peer host */ void addPeerName(String name); /** * Remove peer from this realm * * @param host name of peer host */ void removePeerName(String name); /** * Checks if a peer name belongs to this realm * * @param name name of peer host * * @return true if the the peer belongs to this realm, false otherwise */ boolean hasPeerName(String name); /** * Get the processing agent for this realm * * @return the agent for this realm, if any */ IAgent getAgent(); /** * Get agent configuration values for this realm. * * @return */ IAgentConfiguration getAgentConfiguration(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/controller/IRealmTable.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.controller; import java.util.Collection; import java.util.List; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.InternalException; import org.jdiameter.api.LocalAction; import org.jdiameter.api.Realm; import org.jdiameter.api.RealmTable; import org.jdiameter.client.api.IAnswer; import org.jdiameter.client.api.IRequest; import org.jdiameter.server.api.agent.IAgentConfiguration; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IRealmTable extends RealmTable { Realm matchRealm(IRequest request); Realm matchRealm(IAnswer message, String destRealm); Realm getRealm(String realmName, ApplicationId applicationId); Realm removeRealmApplicationId(String realmName, ApplicationId appId); Collection removeRealm(String realmName); Collection getRealms(String realm); Collection getRealms(); String getRealmForPeer(String fqdn); void addLocalApplicationId(ApplicationId ap); void removeLocalApplicationId(ApplicationId a); void addLocalRealm(String localRealm, String fqdn); /** * Method which accepts IAgentConfiguration to avoid decode, encode, decode sequences * * @param name * @param appId * @param locAction * @param agentConfImpl * @param isDynamic * @param expirationTime * @param hosts * * @return * * @throws InternalException */ Realm addRealm(String name, ApplicationId appId, LocalAction locAction, IAgentConfiguration agentConfImpl, boolean isDynamic, long expirationTime, String[] hosts) throws InternalException; List getAllRealmSet(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/fsm/EventTypes.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.fsm; /** * This enumeration describe all fsm events * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ public enum EventTypes { /** * Connect event */ CONNECT_EVENT(true), /** * Disconnect event */ DISCONNECT_EVENT(true), /** * Operation timeout event */ TIMEOUT_EVENT(true), /** * Start fsm event */ START_EVENT(true), /** * Stop fsm event */ STOP_EVENT(true), /** * Internal error during processing event */ INTERNAL_ERROR(true), /** * Stack received CER message */ CER_EVENT, /** * Stack received CEA message */ CEA_EVENT, /** * Stack received DPR message */ DPR_EVENT, /** * Stack received DPA message */ DPA_EVENT, /** * Stack received DWR message */ DWR_EVENT, /** * Stack received DWA message */ DWA_EVENT, /** * App send message to network */ SEND_MSG_EVENT, /** * Stack received Application message */ RECEIVE_MSG_EVENT; boolean highPriority; EventTypes() { highPriority = false; } EventTypes(boolean highPriority) { this.highPriority = highPriority; } public boolean isHighPriority() { return highPriority; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/fsm/ExecutorFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.fsm; import java.util.concurrent.ExecutorService; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ExecutorFactory { ExecutorService getExecutor(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/fsm/FsmEvent.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.fsm; import org.jdiameter.api.app.StateEvent; import org.jdiameter.client.api.IMessage; /** * This class extends behaviour of FSM StateEvent * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class FsmEvent implements StateEvent { private String key; private EventTypes type; private Object value; private final long createdTime = System.currentTimeMillis(); /** * Create instance of class * * @param type type of event */ public FsmEvent(EventTypes type) { this.type = type; } /** * Create instance of class with predefined parameters * * @param type type of event * @param key event key */ public FsmEvent(EventTypes type, String key) { this(type); this.key = key; } /** * Create instance of class with predefined parameters * * @param type type of event * @param value attached message */ public FsmEvent(EventTypes type, IMessage value) { this(type); this.value = value; } /** * Create instance of class with predefined parameters * * @param type type of event * @param value attached message * @param key event key */ public FsmEvent(EventTypes type, IMessage value, String key) { this(type, value); this.key = key; } /** * Return key value * * @return key value */ public String getKey() { return key; } /** * Return attached message * * @return diameter message */ public IMessage getMessage() { return (IMessage) getData(); } /** * Return created time * * @return created time */ public long getCreatedTime() { return createdTime; } @Override public E encodeType(Class eClass) { return (E) type; } @Override public Enum getType() { return type; } @Override public void setData(Object o) { value = o; } @Override public Object getData() { return value; } @Override public int compareTo(Object o) { return 0; } /** * Return string representation of instance * * @return string representation of instance */ @Override public String toString() { return "Event{name:" + type.name() + ", key:" + key + ", object:" + value + "}"; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/fsm/IContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.fsm; import java.io.IOException; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.OverloadException; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.io.TransportException; /** * This interface describe operations of FSM context object * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IContext { /** * Start connection procedure to remote peer * * @throws InternalException * @throws IOException * @throws org.jdiameter.api.IllegalDiameterStateException */ void connect() throws InternalException, IOException, IllegalDiameterStateException; /** * Start disconnect procedure from remote peer * * @throws InternalException * @throws org.jdiameter.api.IllegalDiameterStateException */ void disconnect() throws InternalException, IllegalDiameterStateException; /** * This method allow sent message to remote peer * * @param message message which one should be sent to remote peer * * @throws TransportException * @throws OverloadException */ boolean sendMessage(IMessage message) throws TransportException, OverloadException; /** * This method allow sent CER command to remote peer * * @throws TransportException * @throws OverloadException */ void sendCerMessage() throws TransportException, OverloadException; /** * This method allow sent CEA command to remote peer * * @param resultCode value for result-code Avp * @param errMessage value for error-message Avp * * @throws TransportException * @throws OverloadException */ void sendCeaMessage(int resultCode, Message cer, String errMessage) throws TransportException, OverloadException; /** * This method allow sent DWR command to remote peer * * @throws TransportException * @throws OverloadException */ void sendDwrMessage() throws TransportException, OverloadException; /** * This method allow sent DWA command to remote peer * * @param dwr parent DWR command receved from remote peer * @param resultCode value for result-code avp * @param errorMessage value for error-message avp * * @throws TransportException * @throws OverloadException */ void sendDwaMessage(IMessage dwr, int resultCode, String errorMessage) throws TransportException, OverloadException; /** * This method allow sent DPR command to remote peer * * @param disconnectCause value for disconnect-cause avp * * @throws TransportException * @throws OverloadException */ void sendDprMessage(int disconnectCause) throws TransportException, OverloadException; /** * This method allow sent DPA command to remote peer * * @param dpr parent DPR command receved from remote peer * @param resultCode value for result-code avp * @param errorMessage value for error-message avp * * @throws TransportException * @throws OverloadException */ void sendDpaMessage(IMessage dpr, int resultCode, String errorMessage) throws TransportException, OverloadException; /** * This method allow processed message from to remote peer * * @param iMessage message from remote peer * * @return true if message correct processed */ boolean receiveMessage(IMessage iMessage); /** * This method call when peer instance receive DWR event * * @param iMessage message * * @return result code With this code stack will be send DWA message */ int processDwrMessage(IMessage iMessage); /** * This method call when peer instance receive DPR event * * @param iMessage message * * @return result code With this code stack will be send DPA message */ int processDprMessage(IMessage iMessage); /** * This method allow sent CEA command to remote peer * * @param key connection key (host + ":" + port) * @param message * * @return true if the message is sent to remote peer */ boolean processCeaMessage(String key, IMessage message); /** * This method allow processed CER command from remote peer * * @param key connection key (host + ":" + port) * @param message received from remote host * * @return result-code for CEA message or -1 if message can not be processed */ int processCerMessage(String key, IMessage message); /** * Return true if connection should be restored Look AttemptToConnect property of peer * * @return true if connection should be restored */ boolean isRestoreConnection(); /** * Reeturn true if connection already created and connected * * @return true if connection already created and connected */ boolean isConnected(); /** * Return parent peer description * * @return parent peer description */ String getPeerDescription(); /** * Clears statistics for context */ void removeStatistics(); /** * Creates statistics for context */ void createStatistics(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/fsm/IFsmFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.fsm; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.common.api.concurrent.IConcurrentFactory; /** * Peer FSM factory * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IFsmFactory { /** * Create instance of Peer FSM * * @param context FSM context object * @param concurrentFactory executor facility * @param config configuration * * @return State machine instance * * @throws InternalException */ IStateMachine createInstanceFsm(IContext context, IConcurrentFactory concurrentFactory, Configuration config) throws InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/fsm/IStateMachine.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.fsm; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.common.api.statistic.IStatistic; /** * This interface extends StateMachine interface * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IStateMachine extends StateMachine { /** * This method returns occupancy of event queue * * @return occupancy of event queue */ double getQueueInfo(); void remStateChangeNotification(StateChangeListener listener); IStatistic getStatistic(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/io/IConnection.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.io; import java.io.IOException; import java.net.InetAddress; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Wrapper; import org.jdiameter.client.api.IMessage; /** * A Connection with a remote host. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IConnection extends Wrapper { /** * Return created time * * @return created time */ long getCreatedTime(); /** * Return identifier of connection. For example: "[remote_host_name]:[remote_port]" * * @return identifier of connection. */ String getKey(); /** * Connect with remote host * * @throws TransportException */ void connect() throws TransportException; /** * Disconnect wit remote host * * @throws InternalError */ void disconnect() throws InternalError; /** * Send message to remote host * * @param message diameter message * * @throws TransportException * @throws OverloadException */ void sendMessage(IMessage message) throws TransportException, OverloadException; /** * Clear all attachec resources (close socket) * * @throws IOException */ void release() throws IOException; /** * Return true if connection is incomming * * @return true if connection is incomming */ boolean isNetworkInitiated(); /** * Return true if is connection is valid * * @return true if is connection is valid */ boolean isConnected(); /** * Return remote host address * * @return remote host address */ InetAddress getRemoteAddress(); /** * Return remote socket port * * @return remote socket port */ int getRemotePort(); /** * Append connection listener * * @param connectionListener listener instance */ void addConnectionListener(IConnectionListener connectionListener); /** * Remove all connection listeners */ void remAllConnectionListener(); /** * Remove connection listener * * @param connectionListener listener instance */ void remConnectionListener(IConnectionListener connectionListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/io/IConnectionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.io; import java.util.List; import org.jdiameter.client.api.IMessage; /** *

      * An object that registers to be notified of events generated by a * IConnection object. *

      * The ConnectionListener interface is implemented by a PCB component. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IConnectionListener { /** * Notifies that connection is created * * @param connKey identifier of created connection */ void connectionOpened(String connKey); /** * Notifies that connection is closed * * @param connKey identifier of closed connection * @param notSended array of not sended messages */ void connectionClosed(String connKey, List notSended); /** * Notifies that connection is received incoming message * * @param connKey identifier of connection * @param message received incoming message */ void messageReceived(String connKey, IMessage message); /** * Notifies that connection is generated excpetion * * @param connKey identifier of connection * @param message the message from that failed * @param cause generated exceptions */ void internalError(String connKey, IMessage message, TransportException cause); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/io/ITransportLayerFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.io; import java.net.InetAddress; import org.jdiameter.api.Wrapper; import org.jdiameter.common.api.concurrent.IConcurrentFactory; /** * Factory of Network Layer elements. Configuration and message parser instances injection by constructor * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ITransportLayerFactory extends Wrapper { /** * Create new IConnection instance with predefined parameters * * @param remoteAddress destination host address * @param factory concurrent factory * @param remotePort destination port address * @param localAddress local network adapter address * @param localPort local socket port * @param ref reference to additional parameters * * @return IConnection instance * * @throws TransportException */ IConnection createConnection(InetAddress remoteAddress, IConcurrentFactory factory, int remotePort, InetAddress localAddress, int localPort, String ref) throws TransportException; /** * Create new IConnection instance with predefined parameters * * @param remoteAddress destination host address * @param factory concurrent factory * @param remotePort destination port address * @param localAddress local network adapter address * @param localPort local socket port * @param listener connection listener instance * @param ref reference to additional parameters * * @return IConnection instance * * @throws TransportException */ IConnection createConnection(InetAddress remoteAddress, IConcurrentFactory factory, int remotePort, InetAddress localAddress, int localPort, IConnectionListener listener, String ref) throws TransportException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/io/NotInitializedException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.io; /** * Signals that an exception has occurred in a during start transport element. An NotInitializedException * is thrown to indicate that transport element is not configured. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class NotInitializedException extends Exception { /** * Create instance of class */ public NotInitializedException() { super(); } /** * Create instance of class with predefined parameters * * @param message error message */ public NotInitializedException(String message) { super(message); } /** * Create instance of class with predefined parameters * * @param message error message * @param cause error cause */ public NotInitializedException(String message, Throwable cause) { super(message, cause); } /** * Create instance of class with predefined parameters * * @param cause error cause */ public NotInitializedException(Throwable cause) { super(cause); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/io/TransportError.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.io; /** * This enumeration describe types on network errors These types help to more details define behaviour of high layers * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public enum TransportError { /** * Internal error (network layer exceptions) */ Internal, /** * Overload errors (overload netowrk queues) */ Overload, /** * Error during send message procedure (special type) */ FailedSendMessage, /** * Received broken message (special type) */ ReceivedBrokenMessage, /** * Network error (io exceptions) */ NetWorkError } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/io/TransportException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.io; /** * Signals that an transport exception has occurred in a during initialize transport element. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class TransportException extends Exception { /** * Error code */ TransportError code; /** * Create instance of class with predefined parameters * * @param message error message * @param code error code */ public TransportException(String message, TransportError code) { super(message); this.code = code; } /** * Create instance of class with predefined parameters * * @param message error message * @param code error code * @param cause error cause */ public TransportException(String message, TransportError code, Throwable cause) { super(message, cause); this.code = code; } /** * Create instance of class with predefined parameters * * @param code error code * @param cause error cause */ public TransportException(TransportError code, Throwable cause) { super(cause); this.code = code; } /** * Return code of error * * @return code of error */ public TransportError getCode() { return code; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/parser/IElementParser.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.parser; import java.net.InetAddress; import java.util.Date; import org.jdiameter.api.AvpDataException; /** * Basic interface for diameter basic elements parsers. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IElementParser { /** * Convert byte array to int * * @param rawData byte representation of int value * * @return int value * * @throws AvpDataException */ int bytesToInt(byte[] rawData) throws AvpDataException; /** * Convert byte array to long * * @param rawData byte representation of long value * * @return long value * * @throws AvpDataException */ long bytesToLong(byte[] rawData) throws AvpDataException; /** * Convert byte array to float * * @param rawData byte representation of float value * * @return float value * * @throws AvpDataException */ float bytesToFloat(byte[] rawData) throws AvpDataException; /** * Convert byte array to double * * @param rawData byte representation of double value * * @return double value * * @throws AvpDataException */ double bytesToDouble(byte[] rawData) throws AvpDataException; /** * Convert byte array to octet string * * @param rawData byte representation of octet string value * * @return octet string value * * @throws AvpDataException */ String bytesToOctetString(byte[] rawData) throws AvpDataException; /** * Convert byte array to utf8 string * * @param rawData byte representation of utf8 string value * * @return utf8 string value * * @throws AvpDataException */ String bytesToUtf8String(byte[] rawData) throws AvpDataException; /** * Convert byte array to date * * @param rawData byte representation of date value * * @return date value * * @throws AvpDataException */ Date bytesToDate(byte[] rawData) throws AvpDataException; /** * Convert byte array to InetAddress * * @param rawData byte representation of InetAddress value * * @return InetAddress value * * @throws AvpDataException */ InetAddress bytesToAddress(byte[] rawData) throws AvpDataException; /** * Convert int to byte array representation * * @param value int value * * @return byte array */ byte[] int32ToBytes(int value); /** * Convert long to 4-byte array representation * * @param value long value * * @return byte array */ byte[] intU32ToBytes(long value); /** * Convert long to byte array representation * * @param value long value * * @return byte array */ byte[] int64ToBytes(long value); /** * Convert float to byte array representation * * @param value float value * * @return byte array */ byte[] float32ToBytes(float value); /** * Convert double to byte array representation * * @param value double value * * @return byte array */ byte[] float64ToBytes(double value); /** * Convert octet string to byte array representation * * @param value octet string value * * @return byte array * * @throws ParseException */ byte[] octetStringToBytes(String value) throws ParseException; /** * Convert utf8 string to byte array representation * * @param value utf8 string value * * @return byte array * * @throws ParseException */ byte[] utf8StringToBytes(String value) throws ParseException; /** * Convert InetAddress to byte array representation * * @param value InetAddress value * * @return byte array */ byte[] addressToBytes(InetAddress value); /** * Convert Date to byte array representation * * @param value Date value * * @return byte array */ byte[] dateToBytes(Date value); /** * Convert byte array to specefied object * * @param rawData byte representation of InetAddress value * @param iface type of object * * @return object instance * * @throws AvpDataException */ T bytesToObject(java.lang.Class iface, byte[] rawData) throws AvpDataException; /** * Convert specified object to byte array representation * * @param value object * * @return byte array * * @throws ParseException */ byte[] objectToBytes(Object value) throws ParseException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/parser/IMessageParser.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.parser; import java.nio.ByteBuffer; import org.jdiameter.api.AvpDataException; import org.jdiameter.client.api.IMessage; /** * Basic interface for diameter message parsers. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IMessageParser { /** * Create message from bytebuffer * * @param data message bytebuffer * * @return instance of message * * @throws AvpDataException */ IMessage createMessage(ByteBuffer data) throws AvpDataException; /** * Create message from byte array * * @param data message byte array * * @return instance of message * * @throws AvpDataException */ IMessage createMessage(byte[] message) throws AvpDataException; /** * Created specified type of message * * @param iface type of message * @param data message bytebuffer * * @return instance of message * * @throws AvpDataException */ T createMessage(java.lang.Class iface, ByteBuffer data) throws AvpDataException; /** * Created empty message * * @param commandCode message command code * @param headerAppId header applicatio id * * @return instance of message */ IMessage createEmptyMessage(int commandCode, long headerAppId); /** * Created specified type of message * * @param iface type of message * @param commandCode message command code * @param headerAppId header applicatio id * * @return instance of message */ T createEmptyMessage(Class iface, int commandCode, long headerAppId); /** * Created new message with copied of header of parent message * * @param parentMessage parent message * * @return instance of message */ IMessage createEmptyMessage(IMessage parentMessage); /** * Created new message with copied of header of parent message * * @param parentMessage parent message * @param commandCode new command code value * * @return instance of message */ IMessage createEmptyMessage(IMessage parentMessage, int commandCode); /** * Created new message with copied of header of parent message * * @param iface type of message * @param parentMessage parent message * * @return instance of message */ T createEmptyMessage(Class iface, IMessage parentMessage); /** * Encode message to ByteBuffer * * @param message diameter message * * @return instance of message * * @throws ParseException */ ByteBuffer encodeMessage(IMessage message) throws ParseException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/parser/ParseException.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.parser; /** * Signals that an parser exception has occurred in a during decoding message * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ParseException extends Exception { private static final long serialVersionUID = 1L; /** * Create instance of class */ public ParseException() { } /** * Create instance of class with predefined parameters * * @param message error message */ public ParseException(String message) { super(message); } /** * Create instance of class with predefined parameters * * @param message error message * @param cause error cause */ public ParseException(String message, Throwable cause) { super(message, cause); } /** * Create instance of class with predefined parameters * * @param cause error cause */ public ParseException(Throwable cause) { super(cause); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/api/router/IRouter.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.api.router; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.InternalException; import org.jdiameter.api.RouteException; import org.jdiameter.client.api.IAnswer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.controller.IPeerTable; import org.jdiameter.client.api.controller.IRealmTable; /** * This class describe Router functionality * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IRouter { /** * Return peer from inner peer table by predefined parameters. Fetches peer based on message content, that is HBH or * realm/host avp contents. Takes into consideration ApplicationId present in message to pick correct realm * definition from RealmTable. This method should be called after {@link #updateRoute}. * * @param message message with routed avps * @param manager instance of peer manager * * @return peer instance * * @throws RouteException * @throws AvpDataException */ IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException, AvpDataException; /** * Return realm table * * @return object representing realm table */ IRealmTable getRealmTable(); /** * Register route information by received request. This information will be used during answer routing. * * @param request request */ void registerRequestRouteInfo(IRequest request); // PCB - Changed to use a better routing mechanism as hopbyhop was not always unique and the table could also grow too big /** * Return Request route info * * @param hopByHopIndentifier Hop-by-Hop Identifier * * @return Array (host and realm) */ String[] getRequestRouteInfo(IMessage message); //PCB added void garbageCollectRequestRouteInfo(IMessage message); /** * Start inner time facilities */ void start(); /** * Stop inner time facilities */ void stop(); /** * Release all resources */ void destroy(); /** * Called when redirect answer is received for request. This method update redirect host information and routes to * new destination. * * @param request * @param answer * @param table */ void processRedirectAnswer(IRequest request, IAnswer answer, IPeerTable table) throws InternalException, RouteException; /** * Based on Redirect entries or any other factors, this method changes route information. * * @param message * * @return * * @throws RouteException * @throws AvpDataException */ boolean updateRoute(IRequest message) throws RouteException, AvpDataException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/AbstractStateChangeListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import org.jdiameter.api.app.StateChangeListener; /** * Implementation of state change methods. Developer can provide implementation of particular methods required. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public abstract class AbstractStateChangeListener implements StateChangeListener { /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Enum, java.lang.Enum) */ @Override @SuppressWarnings("unchecked") public void stateChanged(Enum oldState, Enum newState) { // Stub method } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override @SuppressWarnings("unchecked") public void stateChanged(T source, Enum oldState, Enum newState) { // Stub method } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/BaseSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import static org.jdiameter.client.impl.helpers.Parameters.MessageTimeOut; import static org.jdiameter.client.impl.helpers.Parameters.SessionTimeOut; import java.io.Serializable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.*; import org.jdiameter.client.api.IAssembler; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IEventListener; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.common.api.timer.ITimerFacility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Implementation for {@link BaseSession}. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public abstract class BaseSessionImpl implements BaseSession { private static final Logger logger = LoggerFactory.getLogger(BaseSessionImpl.class); protected final long creationTime = System.currentTimeMillis(); protected long lastAccessedTime = creationTime; protected boolean isValid = true; protected String sessionId; protected long maxIdleTime = 0; protected transient IContainer container; protected transient IMessageParser parser; protected NetworkReqListener reqListener; protected Serializable istTimerId; @Override public long getCreationTime() { return creationTime; } @Override public long getLastAccessedTime() { return lastAccessedTime; } protected long setLastAccessTime() { lastAccessedTime = System.currentTimeMillis(); if (sessionId != null) { maxIdleTime = container.getConfiguration().getLongValue(SessionTimeOut.ordinal(), (Long) SessionTimeOut.defValue()); if (maxIdleTime > 0) { IAssembler assembler = container.getAssemblerFacility(); ITimerFacility timerFacility = assembler.getComponentInstance(ITimerFacility.class); if (istTimerId != null) { timerFacility.cancel(istTimerId); } istTimerId = timerFacility.schedule(this.getSessionId(), IDLE_SESSION_TIMER_NAME, maxIdleTime); } } return lastAccessedTime; } public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { if (!isValid() || (maxIdleTime > 0 && System.currentTimeMillis() - getLastAccessedTime() >= maxIdleTime)) { logger.debug("Terminating idle/invalid application session [{}] with SID[{}]", this, getSessionId()); this.release(); } } } @Override public boolean isValid() { return isValid; } @Override public String getSessionId() { return sessionId; } /* * (non-Javadoc) * * @see org.jdiameter.api.BaseSession#isAppSession() */ @Override public boolean isAppSession() { return false; } /* * (non-Javadoc) * * @see org.jdiameter.api.BaseSession#isReplicable() */ @Override public boolean isReplicable() { return false; } protected void genericSend(Message message, EventListener listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { if (isValid) { long timeOut = container.getConfiguration().getLongValue(MessageTimeOut.ordinal(), (Long) MessageTimeOut.defValue()); genericSend(message, listener, timeOut, TimeUnit.MILLISECONDS); } else { throw new IllegalDiameterStateException("Session already released"); } } protected void genericSend(Message aMessage, EventListener listener, long timeout, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { if (isValid) { setLastAccessTime(); IMessage message = (IMessage) aMessage; IEventListener localListener = createListenerWrapper(listener); if (message.isRequest()) { message.setListener(localListener); // Auto set system avps if (message.getAvps().getAvpByIndex(0).getCode() != Avp.SESSION_ID && sessionId != null) { // Just to make sure it doesn't get duplicated message.getAvps().removeAvp(Avp.SESSION_ID); message.getAvps().insertAvp(0, Avp.SESSION_ID, sessionId, true, false, false); } } //Add Origin-Host/Realm AVPs if not present MessageUtility.addOriginAvps(aMessage, container.getMetaData()); if (message.getState() != IMessage.STATE_NOT_SENT && message.getState() != IMessage.STATE_ANSWERED) { throw new IllegalDiameterStateException("Illegal state"); } message.createTimer(container.getScheduledFacility(), timeout, timeUnit); try { container.sendMessage(message); } catch (RouteException e) { message.clearTimer(); throw e; } catch (Exception e) { message.clearTimer(); throw new InternalException(e); } } else { throw new IllegalDiameterStateException("Session already released"); } } @SuppressWarnings("unchecked") protected IEventListener createListenerWrapper(final EventListener listener) { return listener == null ? null : new MyEventListener(this, listener); } public Future send(final Message message) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { MyFuture future = new MyFuture(); future.send(message); return future; } public Future send(Message message, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { MyFuture future = new MyFuture(); future.send(message, timeOut, timeUnit); return future; } private class MyFuture implements Future { private boolean canceled; private boolean done; private boolean timeOut; private Lock lock = new ReentrantLock(); private CountDownLatch block = new CountDownLatch(1); private Message result; @Override public boolean cancel(boolean mayInterruptIfRunning) { lock.lock(); try { canceled = true; done = false; block.countDown(); } finally { lock.unlock(); } return true; } @Override public boolean isCancelled() { return canceled; } @Override public boolean isDone() { return done; } @Override public Message get() throws InterruptedException, ExecutionException { try { block.await(); } catch (Exception e) { throw new ExecutionException(e); } Message rc = canceled ? null : result; result = null; return rc; } @Override public Message get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { try { block.await(timeout, unit); } catch (Exception e) { throw new ExecutionException(e); } if (timeOut) { throw new TimeoutException(); } Message rc = canceled ? null : result; result = null; return rc; } private IEventListener createListener() { return new IEventListener() { @Override public void setValid(boolean value) { } @Override public boolean isValid() { return !canceled; } @Override public void receivedSuccessMessage(Request r, Answer a) { lock.lock(); try { if (!canceled) { result = a; canceled = false; done = true; } block.countDown(); } finally { lock.unlock(); } } @Override public void timeoutExpired(Request message) { lock.lock(); try { if (!canceled) { done = true; timeOut = true; } block.countDown(); } finally { lock.unlock(); } } }; } public void send(Message message) throws RouteException, OverloadException, IllegalDiameterStateException, InternalException { genericSend(message, createListener()); } public void send(Message message, long timeOut, TimeUnit timeUnit) throws RouteException, OverloadException, IllegalDiameterStateException, InternalException { genericSend(message, createListener(), timeOut, timeUnit); } } /** * Appends an *-Application-Id AVP to the message, if none is present already. * * @param appId the application-id value * @param m the message to append the *-Application-Id */ protected void appendAppId(ApplicationId appId, Message m) { if (appId == null) { return; } // check if any application-id avp is already present. // we could use m.getApplicationIdAvps().size() > 0 but this should spare a few cpu cycles for (Avp avp : m.getAvps()) { int code = avp.getCode(); if (code == Avp.ACCT_APPLICATION_ID || code == Avp.AUTH_APPLICATION_ID || code == Avp.VENDOR_SPECIFIC_APPLICATION_ID) { return; } } if (appId.getVendorId() == 0) { if (appId.getAcctAppId() != 0) { m.getAvps().addAvp(Avp.ACCT_APPLICATION_ID, appId.getAcctAppId(), true, false, true); } if (appId.getAuthAppId() != 0) { m.getAvps().addAvp(Avp.AUTH_APPLICATION_ID, appId.getAuthAppId(), true, false, true); } } else { AvpSet avp = m.getAvps().addGroupedAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, true, false); avp.addAvp(Avp.VENDOR_ID, appId.getVendorId(), true, false, true); if (appId.getAuthAppId() != 0) { avp.addAvp(Avp.AUTH_APPLICATION_ID, appId.getAuthAppId(), true, false, true); } if (appId.getAcctAppId() != 0) { avp.addAvp(Avp.ACCT_APPLICATION_ID, appId.getAcctAppId(), true, false, true); } } } protected long getAppId(ApplicationId appId) { if (appId == null) { return 0; } // if (appId.getVendorId() == 0) { if (appId.getAcctAppId() != 0) { return appId.getAcctAppId(); } if (appId.getAuthAppId() != 0) { return appId.getAuthAppId(); } // } return appId.getVendorId(); } } @SuppressWarnings("all") //3rd party lib class MyEventListener implements IEventListener { BaseSessionImpl session; EventListener listener; boolean isValid = true; MyEventListener(BaseSessionImpl session, EventListener listener) { this.session = session; this.listener = listener; } @Override public void setValid(boolean value) { isValid = value; if (!isValid) { session = null; listener = null; } } @Override public boolean isValid() { return isValid; } @Override @SuppressWarnings("unchecked") public void receivedSuccessMessage(Request request, Answer answer) { if (isValid) { session.setLastAccessTime(); listener.receivedSuccessMessage(request, answer); } } @Override @SuppressWarnings("unchecked") public void timeoutExpired(Request message) { if (isValid) { session.setLastAccessTime(); listener.timeoutExpired(message); } } @Override public int hashCode() { return listener == null ? 0 : listener.hashCode(); } @Override public boolean equals(Object obj) { return listener != null && listener.equals(obj); } @Override public String toString() { return listener == null ? "null" : listener.toString(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/DictionarySingleton.java ================================================ /* * JBoss, Home of Professional Open Source * Copyright 2010, 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.jdiameter.client.impl; import org.jdiameter.api.InternalException; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.api.validation.ValidatorLevel; import org.jdiameter.common.impl.validation.DictionaryImpl; import java.io.InputStream; /** * Util class. Makes it easier to access Dictionary instance as singleton. * * @author Bartosz Baranowski * @author Alexandre Mendonca * @since 1.5.4.0-build404 */ @SuppressWarnings("all") //3rd party lib public class DictionarySingleton { private DictionarySingleton() { // defeat instantiation } public static Dictionary getDictionary() { return DictionaryImpl.getInstance((String) null); } public static Dictionary getDictionary(String confFile) { return DictionaryImpl.getInstance(confFile); } public static Dictionary getDictionary(InputStream is) { return DictionaryImpl.getInstance(is); } static void init(String clazz, boolean validatorEnabled, ValidatorLevel validatorSendLevel, ValidatorLevel validatorReceiveLevel) throws InternalException { try { Class.forName(clazz).getMethod("getInstance", String.class).invoke(null, new Object[]{null}); DictionaryImpl.INSTANCE.setEnabled(validatorEnabled); DictionaryImpl.INSTANCE.setSendLevel(validatorSendLevel); DictionaryImpl.INSTANCE.setReceiveLevel(validatorReceiveLevel); } catch (Exception e) { throw new InternalException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/MessageUtility.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Message; import org.jdiameter.api.MetaData; /** * Small util class to separate AVP manipulation code from MessageParser class. * * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class MessageUtility { private MessageUtility() { } /** * Used to set origin, previously done in MessageParser. * * @param m * @param md */ public static void addOriginAvps(Message m, MetaData md) { // FIXME: check for "userFqnAsUri" ? AvpSet set = m.getAvps(); if (set.getAvp(Avp.ORIGIN_HOST) == null) { m.getAvps().addAvp(Avp.ORIGIN_HOST, md.getLocalPeer().getUri().getFQDN(), true, false, true); } if (set.getAvp(Avp.ORIGIN_REALM) == null) { m.getAvps().addAvp(Avp.ORIGIN_REALM, md.getLocalPeer().getRealmName(), true, false, true); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/MetaDataImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import static org.jdiameter.client.impl.helpers.Parameters.*; import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; import java.lang.management.MemoryType; import java.lang.management.MemoryUsage; import java.net.InetAddress; import java.net.URISyntaxException; import java.net.UnknownHostException; import java.net.UnknownServiceException; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Configuration; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Peer; import org.jdiameter.api.PeerState; import org.jdiameter.api.PeerStateListener; import org.jdiameter.api.StackType; import org.jdiameter.api.URI; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IMetaData; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.fsm.EventTypes; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.impl.helpers.IPConverter; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.jdiameter.common.impl.controller.AbstractPeer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Use stack extension point * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class MetaDataImpl implements IMetaData { private static final Logger logger = LoggerFactory.getLogger(MetaDataImpl.class); protected List beans = ManagementFactory.getMemoryPoolMXBeans(); protected IContainer stack; protected long state; protected IPeer peer; protected Set appIds = new LinkedHashSet(); protected final ISessionDatasource sessionDataSource; public MetaDataImpl(IContainer s) { this.stack = s; this.sessionDataSource = s.getAssemblerFacility().getComponentInstance(ISessionDatasource.class); } public MetaDataImpl(IContainer s, IStatisticManager statisticFactory) { this(s); this.peer = newLocalPeer(statisticFactory); IStatisticRecord heapMemory = statisticFactory.newCounterRecord(IStatisticRecord.Counters.HeapMemory, new IStatisticRecord.LongValueHolder() { @Override public long getValueAsLong() { for (MemoryPoolMXBean bean : beans) { MemoryType memoryType = bean.getType(); MemoryUsage memoryUsage = bean.getUsage(); if (memoryType == MemoryType.HEAP) { return memoryUsage.getUsed(); } } return 0; } @Override public String getValueAsString() { return String.valueOf(getValueAsLong()); } }); IStatisticRecord noHeapMemory = statisticFactory.newCounterRecord(IStatisticRecord.Counters.NoHeapMemory, new IStatisticRecord.LongValueHolder() { @Override public long getValueAsLong() { for (MemoryPoolMXBean bean : beans) { MemoryType memoryType = bean.getType(); MemoryUsage memoryUsage = bean.getUsage(); if (memoryType != MemoryType.HEAP) { return memoryUsage.getUsed(); } } return 0; } @Override public String getValueAsString() { return String.valueOf(getValueAsLong()); } }); peer.getStatistic().appendCounter(heapMemory, noHeapMemory); } protected IPeer newLocalPeer(IStatisticManager statisticFactory) { return new ClientLocalPeer(statisticFactory); } @Override public Peer getLocalPeer() { return peer; } @Override public int getMajorVersion() { return 2; } @Override public int getMinorVersion() { return 1; } @Override public StackType getStackType() { return StackType.TYPE_CLIENT; } @Override public Configuration getConfiguration() { return stack.getConfiguration(); } @Override public void updateLocalHostStateId() { state = System.currentTimeMillis(); } @Override public long getLocalHostStateId() { return state; } @Override public boolean isWrapperFor(Class aClass) throws InternalException { return aClass == IMetaData.class; } @Override @SuppressWarnings("unchecked") public T unwrap(Class aClass) throws InternalException { if (aClass == IMetaData.class) { return (T) this; } return null; } protected class ClientLocalPeer extends AbstractPeer implements IPeer { protected AtomicLong hopByHopId = new AtomicLong(0); protected InetAddress[] addresses = new InetAddress[0]; public void resetAddresses() { addresses = new InetAddress[0]; } @Override public void connect() throws IllegalDiameterStateException { throw new IllegalDiameterStateException("Illegal operation"); } @Override public void disconnect(int disconnectCause) throws IllegalDiameterStateException { throw new IllegalDiameterStateException("Illegal operation"); } public ClientLocalPeer(IStatisticManager statisticFactory) { //FIXME: remove NULL? super(null, statisticFactory); createPeerStatistics(); } @Override @SuppressWarnings("unchecked") public E getState(Class anEnum) { switch (stack.getState()) { case IDLE: return (E) PeerState.DOWN; case CONFIGURED: return (E) PeerState.INITIAL; case STARTED: return (E) PeerState.OKAY; case STOPPED: return (E) PeerState.SUSPECT; } return (E) PeerState.DOWN; } @Override public URI getUri() { try { return new URI( stack.getConfiguration().getStringValue(OwnDiameterURI.ordinal(), (String) OwnDiameterURI.defValue())); } catch (URISyntaxException e) { throw new IllegalArgumentException(e); } catch (UnknownServiceException e) { throw new IllegalArgumentException(e); } } @Override public String getRealmName() { return stack.getConfiguration().getStringValue(OwnRealm.ordinal(), (String) OwnRealm.defValue()); } @Override public long getVendorId() { return stack.getConfiguration().getLongValue(OwnVendorID.ordinal(), (Long) OwnVendorID.defValue()); } @Override public String getProductName() { return stack.getConfiguration().getStringValue(OwnProductName.ordinal(), (String) OwnProductName.defValue()); } @Override public long getFirmware() { return stack.getConfiguration().getLongValue(OwnFirmwareRevision.ordinal(), -1L); } @Override public Set getCommonApplications() { if (logger.isDebugEnabled()) { logger.debug("In getCommonApplications appIds size is [{}]", appIds.size()); } if (appIds.isEmpty()) { Configuration[] apps = stack.getConfiguration().getChildren(ApplicationId.ordinal()); if (apps != null) { if (logger.isDebugEnabled()) { logger.debug("Stack configuration has apps list size of [{}]. Looping through them", apps.length); } for (Configuration a : apps) { long vnd = a.getLongValue(VendorId.ordinal(), 0L); long auth = a.getLongValue(AuthApplId.ordinal(), 0L); long acc = a.getLongValue(AcctApplId.ordinal(), 0L); if (logger.isDebugEnabled()) { logger.debug("Adding app id vendor [{}] auth [{}] acc [{}]", new Object[] { vnd, auth, acc }); } if (auth != 0) { appIds.add(org.jdiameter.api.ApplicationId.createByAuthAppId(vnd, auth)); } if (acc != 0) { appIds.add(org.jdiameter.api.ApplicationId.createByAccAppId(vnd, acc)); } } } else { logger.debug("Apps is null - we have no apps in the stack configuration."); } } return appIds; } @Override public InetAddress[] getIPAddresses() { if (addresses.length == 0) { String address = stack.getConfiguration().getStringValue(OwnIPAddress.ordinal(), null); if (address == null || address.length() == 0) { try { addresses = new InetAddress[] { InetAddress.getByName(getUri().getFQDN()) }; } catch (UnknownHostException e) { logger.debug("Can not get IP by URI {}", e); try { addresses = new InetAddress[] { InetAddress.getLocalHost() }; } catch (UnknownHostException e1) { addresses = new InetAddress[0]; } } } else { InetAddress ia = IPConverter.InetAddressByIPv4(address); if (ia == null) { ia = IPConverter.InetAddressByIPv6(address); } if (ia == null) { try { addresses = new InetAddress[] { InetAddress.getLocalHost() }; } catch (UnknownHostException e) { addresses = new InetAddress[0]; } } else { addresses = new InetAddress[] { ia }; } } } return addresses; } @Override public IStatistic getStatistic() { return statistic; } @Override public String toString() { return "Peer{" + "\n\tUri=" + getUri() + "; RealmName=" + getRealmName() + "; VendorId=" + getVendorId() + ";\n\tProductName=" + getProductName() + "; FirmWare=" + getFirmware() + ";\n\tAppIds=" + getCommonApplications() + ";\n\tIPAddresses=" + Arrays.asList(getIPAddresses()).toString() + ";" + "\n}"; } @Override public int getRating() { return 0; } @Override public void addPeerStateListener(PeerStateListener peerStateListener) { } @Override public void removePeerStateListener(PeerStateListener peerStateListener) { } @Override public long getHopByHopIdentifier() { return hopByHopId.incrementAndGet(); } @Override public void addMessage(IMessage message) { } @Override public void remMessage(IMessage message) { } @Override public IMessage[] remAllMessage() { return new IMessage[0]; } @Override public boolean handleMessage(EventTypes type, IMessage message, String key) throws TransportException, OverloadException, InternalException { return false; } @Override public boolean sendMessage(IMessage message) throws TransportException, OverloadException { return false; } @Override public boolean hasValidConnection() { return false; } @Override public void setRealm(String realm) { } @Override public void addStateChangeListener(StateChangeListener listener) { } @Override public void remStateChangeListener(StateChangeListener listener) { } @Override public void addConnectionListener(IConnectionListener listener) { } @Override public void remConnectionListener(IConnectionListener listener) { } /* * (non-Javadoc) * * @see org.jdiameter.client.api.controller.IPeer#isConnected() */ @Override public boolean isConnected() { return true; // it's own peer } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/RawSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import java.util.concurrent.TimeUnit; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RawSession; import org.jdiameter.api.RouteException; import org.jdiameter.api.Session; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RawSessionImpl extends BaseSessionImpl implements RawSession { RawSessionImpl(IContainer stack) { container = stack; this.parser = container.getAssemblerFacility().getComponentInstance(IMessageParser.class); } @Override public Message createMessage(int commandCode, ApplicationId appId, Avp... avps) { if (isValid) { setLastAccessTime(); IMessage m = parser.createEmptyMessage(commandCode, getAppId(appId)); m.getAvps().addAvp(avps); appendAppId(appId, m); return m; } else { throw new IllegalStateException("Session already released"); } } @Override public Message createMessage(int commandCode, ApplicationId appId, long hopByHopIdentifier, long endToEndIdentifier, Avp... avps) { if (isValid) { setLastAccessTime(); IMessage m = parser.createEmptyMessage(commandCode, getAppId(appId)); if (hopByHopIdentifier >= 0) { m.setHopByHopIdentifier(-hopByHopIdentifier); } if (endToEndIdentifier >= 0) { m.setEndToEndIdentifier(endToEndIdentifier); } m.getAvps().addAvp(avps); appendAppId(appId, m); return m; } else { throw new IllegalStateException("Session already released"); } } @Override public Message createMessage(Message message, boolean copyAvps) { if (isValid) { setLastAccessTime(); IMessage newMessage = null; IMessage inner = (IMessage) message; if (copyAvps) { newMessage = parser.createEmptyMessage(inner); MessageUtility.addOriginAvps(newMessage, container.getMetaData()); } else { newMessage = (IMessage) createMessage( inner.getCommandCode(), inner.getSingleApplicationId(), -1, -1); } newMessage.setRequest(message.isRequest()); newMessage.setProxiable(message.isProxiable()); newMessage.setError(message.isError()); newMessage.setReTransmitted(message.isReTransmitted()); return newMessage; } else { throw new IllegalStateException("Session already released"); } } @Override public void send(Message message, EventListener listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { genericSend(message, listener); } @Override public void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { genericSend(message, listener, timeOut, timeUnit); } @Override public void release() { isValid = false; container = null; parser = null; } @Override public boolean isWrapperFor(Class iface) throws InternalException { return iface == Session.class; } @Override public T unwrap(Class iface) throws InternalException { return (T) (iface == Session.class ? new SessionImpl(container) : null); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/SessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.InternalException; import org.jdiameter.api.RawSession; import org.jdiameter.api.Session; import org.jdiameter.api.app.AppSession; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.api.StackState; import org.jdiameter.client.impl.helpers.UIDGenerator; import org.jdiameter.common.api.app.IAppSessionFactory; import org.jdiameter.common.api.data.ISessionDatasource; /** * Implementation for {@link ISessionFactory} * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class SessionFactoryImpl implements ISessionFactory { private IContainer stack; @SuppressWarnings("rawtypes") private Map appFactories = new ConcurrentHashMap(); private ISessionDatasource dataSource; protected static UIDGenerator uid = new UIDGenerator(); public SessionFactoryImpl(IContainer stack) { this.stack = stack; this.dataSource = this.stack.getAssemblerFacility().getComponentInstance(ISessionDatasource.class); } @Override public String getSessionId(String custom) { long id = uid.nextLong(); long high32 = (id & 0xffffffff00000000L) >> 32; long low32 = (id & 0xffffffffL); StringBuilder sb = new StringBuilder(); sb.append(stack.getMetaData().getLocalPeer().getUri().getFQDN()).append(";").append(high32).append(";").append(low32); if (custom != null) { //FIXME: add checks for not allowed chars? sb.append(";").append(custom); } return sb.toString(); } @Override public String getSessionId() { return this.getSessionId(null); } @Override public RawSession getNewRawSession() throws InternalException { if (stack.getState() == StackState.IDLE) { throw new InternalException("Illegal state of stack"); } return new RawSessionImpl(stack); } @Override public Session getNewSession() throws InternalException { if (stack.getState() == StackState.IDLE) { throw new InternalException("Illegal state of stack"); } // FIXME: store this! Properly handle in ISessiondata SessionImpl session = new SessionImpl(stack); this.dataSource.addSession(session); return session; } @Override public Session getNewSession(String sessionId) throws InternalException { if (stack.getState() == StackState.IDLE) { throw new InternalException("Illegal state of stack"); } SessionImpl session = new SessionImpl(stack); if (sessionId != null && sessionId.length() > 0) { session.sessionId = sessionId; } // FIXME: store this! Properly handle in ISessiondata this.dataSource.addSession(session); return session; } @Override @SuppressWarnings("unchecked") public T getNewAppSession(ApplicationId applicationId, Class aClass) throws InternalException { return (T) getNewAppSession(null, applicationId, aClass, new Object[0]); } @Override @SuppressWarnings("unchecked") public T getNewAppSession(String sessionId, ApplicationId applicationId, Class aClass) throws InternalException { return (T) getNewAppSession(sessionId, applicationId, aClass, new Object[0]); } @Override @SuppressWarnings("unchecked") public T getNewAppSession(String sessionId, ApplicationId applicationId, Class aClass, Object... args) throws InternalException { T session = null; if (stack.getState() == StackState.IDLE) { throw new InternalException("Illegal state of stack"); } if (appFactories.containsKey(aClass)) { session = (T) appFactories.get(aClass).getNewSession(sessionId, aClass, applicationId, args); // FIXME: add check if it exists already! //dataSource.addSession(session); } return session; } @Override public void registerAppFacory(Class sessionClass, IAppSessionFactory factory) { appFactories.put(sessionClass, factory); } @Override public void unRegisterAppFacory(Class sessionClass) { appFactories.remove(sessionClass); } /* * (non-Javadoc) * * @see org.jdiameter.client.api.ISessionFactory#getAppSessionFactory(java.lang.Class) */ @Override public IAppSessionFactory getAppSessionFactory(Class sessionClass) { return appFactories.get(sessionClass); } @Override public IContainer getContainer() { return stack; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/SessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RawSession; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.ISession; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.api.timer.ITimerFacility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Implementation for {@link ISession} * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class SessionImpl extends BaseSessionImpl implements ISession { private static final Logger logger = LoggerFactory.getLogger(SessionImpl.class); private Semaphore lock = new Semaphore(1); // container lock SessionImpl(IContainer container) { setContainer(container); try { sessionId = container.getSessionFactory().getSessionId(); } catch (IllegalDiameterStateException idse) { throw new IllegalStateException("Unable to generate Session-Id", idse); } } void setContainer(IContainer container) { try { lock.acquire(); // allow container change only if not releasing this.container = container; this.parser = (IMessageParser) container.getAssemblerFacility().getComponentInstance(IMessageParser.class); } catch (InterruptedException e) { logger.error("failure getting lock", e); } finally { lock.release(); } } @Override public void send(Message message, EventListener listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { genericSend(message, listener); } @Override public void send(Message message, EventListener listener, long timeout, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { genericSend(message, listener, timeout, timeUnit); } @Override public void setRequestListener(NetworkReqListener listener) { if (listener != null) { super.reqListener = listener; container.addSessionListener(sessionId, listener); } } @Override public NetworkReqListener getReqListener() { return super.reqListener; } @Override public Request createRequest(int commandCode, ApplicationId appId, String destRealm) { if (isValid) { setLastAccessTime(); IRequest m = parser.createEmptyMessage(IRequest.class, commandCode, getAppId(appId)); m.setNetworkRequest(false); m.setRequest(true); m.getAvps().addAvp(Avp.SESSION_ID, sessionId, true, false, false); appendAppId(appId, m); if (destRealm != null) { m.getAvps().addAvp(Avp.DESTINATION_REALM, destRealm, true, false, true); } MessageUtility.addOriginAvps(m, container.getMetaData()); return m; } else { throw new IllegalStateException("Session already released"); } } @Override public Request createRequest(int commandCode, ApplicationId appId, String destRealm, String destHost) { if (isValid) { setLastAccessTime(); IRequest m = parser.createEmptyMessage(IRequest.class, commandCode, getAppId(appId)); m.setNetworkRequest(false); m.setRequest(true); m.getAvps().addAvp(Avp.SESSION_ID, sessionId, true, false, false); appendAppId(appId, m); if (destRealm != null) { m.getAvps().addAvp(Avp.DESTINATION_REALM, destRealm, true, false, true); } if (destHost != null) { m.getAvps().addAvp(Avp.DESTINATION_HOST, destHost, true, false, true); } MessageUtility.addOriginAvps(m, container.getMetaData()); return m; } else { throw new IllegalStateException("Session already released"); } } @Override public Request createRequest(Request prevRequest) { if (isValid) { setLastAccessTime(); IRequest request = parser.createEmptyMessage(Request.class, (IMessage) prevRequest); request.setRequest(true); request.setNetworkRequest(false); MessageUtility.addOriginAvps(request, container.getMetaData()); return request; } else { throw new IllegalStateException("Session already released"); } } @Override public void release() { isValid = false; try { lock.acquire(); // prevent container NullPointerException if (container != null) { if (istTimerId != null) { container.getAssemblerFacility().getComponentInstance(ITimerFacility.class).cancel(istTimerId); } container.removeSessionListener(sessionId); container.getAssemblerFacility().getComponentInstance(ISessionDatasource.class).removeSession(sessionId); } container = null; parser = null; reqListener = null; } catch (InterruptedException e) { logger.error("failure getting lock", e); } finally { lock.release(); } } @Override public boolean isWrapperFor(Class iface) throws InternalException { return iface == RawSession.class; } @Override @SuppressWarnings("unchecked") public T unwrap(Class iface) throws InternalException { return (T) (iface == RawSession.class ? new RawSessionImpl(container) : null); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/StackImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import static org.jdiameter.client.impl.helpers.ExtensionPoint.ControllerLayer; import static org.jdiameter.client.impl.helpers.ExtensionPoint.StackLayer; import static org.jdiameter.client.impl.helpers.ExtensionPoint.TransportLayer; import static org.jdiameter.client.impl.helpers.Parameters.Assembler; import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.ProcessingMessageTimer; import java.io.IOException; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.BaseSession; import org.jdiameter.api.Configuration; import org.jdiameter.api.DisconnectCause; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.MetaData; import org.jdiameter.api.Mode; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.Peer; import org.jdiameter.api.PeerState; import org.jdiameter.api.PeerTable; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.api.validation.ValidatorLevel; import org.jdiameter.client.api.IAssembler; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IMetaData; import org.jdiameter.client.api.StackState; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.controller.IPeerTable; import org.jdiameter.client.impl.helpers.Parameters; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.api.statistic.IStatisticProcessor; import org.jdiameter.common.api.timer.ITimerFacility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Use stack extension point * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class StackImpl implements IContainer, StackImplMBean { private static final Logger log = LoggerFactory.getLogger(StackImpl.class); protected IAssembler assembler; protected IConcurrentFactory concurrentFactory; protected Configuration config; protected IPeerTable peerManager; protected StackState state = StackState.IDLE; protected Lock lock = new ReentrantLock(); /** * Use for processing request time-out tasks (for all active peers) */ protected ScheduledExecutorService scheduledFacility; @Override @SuppressWarnings("unchecked") public SessionFactory init(Configuration config) throws IllegalDiameterStateException, InternalException { lock.lock(); if (log.isInfoEnabled()) { log.info("(-)(-)(-)(-)(-) Initialising " + VersionProperties.instance.getProperty("vendor") + " DIAMETER Stack v" + VersionProperties.instance.getProperty("version") + " (-)(-)(-)(-)(-)"); } try { if (state != StackState.IDLE) { throw new IllegalDiameterStateException(); } try { Class assemblerClass = Class.forName(config.getStringValue(Assembler.ordinal(), (String) Assembler.defValue())); assembler = (IAssembler) assemblerClass.getConstructor(Configuration.class).newInstance(config); // register common instances assembler.registerComponentInstance(this); assembler.registerComponentInstance(config); } catch (Exception e) { throw new InternalException(e); } this.config = config; this.concurrentFactory = assembler.getComponentInstance(IConcurrentFactory.class); try { Configuration[] dictionaryConfigs = config.getChildren(Parameters.Dictionary.ordinal()); // Initialize with default values String dictionaryClassName = (String) Parameters.DictionaryClass.defValue(); Boolean validatorEnabled = (Boolean) Parameters.DictionaryEnabled.defValue(); ValidatorLevel validatorSendLevel = ValidatorLevel .fromString((String) Parameters.DictionarySendLevel.defValue()); ValidatorLevel validatorReceiveLevel = ValidatorLevel .fromString((String) Parameters.DictionaryReceiveLevel.defValue()); if (dictionaryConfigs != null && dictionaryConfigs.length > 0) { Configuration dictionaryConfiguration = dictionaryConfigs[0]; dictionaryClassName = dictionaryConfiguration.getStringValue(Parameters.DictionaryClass.ordinal(), (String) Parameters.DictionaryClass.defValue()); validatorEnabled = dictionaryConfiguration.getBooleanValue(Parameters.DictionaryEnabled.ordinal(), (Boolean) Parameters.DictionaryEnabled.defValue()); validatorSendLevel = ValidatorLevel.fromString(dictionaryConfiguration.getStringValue( Parameters.DictionarySendLevel.ordinal(), (String) Parameters.DictionarySendLevel.defValue())); validatorReceiveLevel = ValidatorLevel .fromString(dictionaryConfiguration.getStringValue(Parameters.DictionaryReceiveLevel.ordinal(), (String) Parameters.DictionaryReceiveLevel.defValue())); } createDictionary(dictionaryClassName, validatorEnabled, validatorSendLevel, validatorReceiveLevel); } catch (Exception e) { throw new InternalException(e); } // create manager this.peerManager = assembler.getComponentInstance(IPeerTable.class); this.peerManager.setAssembler(assembler); this.state = StackState.CONFIGURED; } finally { lock.unlock(); } return assembler.getComponentInstance(SessionFactory.class); } private void createDictionary(String clazz, boolean validatorEnabled, ValidatorLevel validatorSendLevel, ValidatorLevel validatorReceiveLevel) throws InternalException { // Defer call to singleton DictionarySingleton.init(clazz, validatorEnabled, validatorSendLevel, validatorReceiveLevel); } @Override public SessionFactory getSessionFactory() throws IllegalDiameterStateException { if (state == StackState.CONFIGURED || state == StackState.STARTED) { // FIXME: When possible, get rid of IoC here. return assembler.getComponentInstance(SessionFactory.class); } else { throw new IllegalDiameterStateException(); } } @Override public Dictionary getDictionary() throws IllegalDiameterStateException { return DictionarySingleton.getDictionary(); } @Override public void start() throws IllegalDiameterStateException, InternalException { lock.lock(); try { if (state != StackState.STOPPED && state != StackState.CONFIGURED) { throw new IllegalDiameterStateException(); } scheduledFacility = concurrentFactory.getScheduledExecutorService(ProcessingMessageTimer.name()); assembler.getComponentInstance(ISessionDatasource.class).start(); assembler.getComponentInstance(IStatisticProcessor.class).start(); assembler.getComponentInstance(ITimerFacility.class); startPeerManager(); state = StackState.STARTED; } finally { lock.unlock(); } } @Override @SuppressWarnings("unchecked") public void start(final Mode mode, long timeOut, TimeUnit timeUnit) throws IllegalDiameterStateException, InternalException { lock.lock(); try { if (state != StackState.STOPPED && state != StackState.CONFIGURED) { throw new IllegalDiameterStateException(); } scheduledFacility = concurrentFactory.getScheduledExecutorService(ProcessingMessageTimer.name()); assembler.getComponentInstance(IStatisticProcessor.class).start(); assembler.getComponentInstance(ISessionDatasource.class).start(); assembler.getComponentInstance(ITimerFacility.class); List peerTable = peerManager.getPeerTable(); // considering only "to connect" peers are on the table at this time... final CountDownLatch barrier = new CountDownLatch( Mode.ANY_PEER.equals(mode) ? Math.min(peerTable.size(), 1) : peerTable.size()); StateChangeListener listener = new AbstractStateChangeListener() { @Override public void stateChanged(Enum oldState, Enum newState) { if (PeerState.OKAY.equals(newState)) { barrier.countDown(); } } }; for (Peer p : peerTable) { ((IPeer) p).addStateChangeListener(listener); } startPeerManager(); try { barrier.await(timeOut, timeUnit); if (barrier.getCount() != 0) { throw new InternalException("TimeOut"); } state = StackState.STARTED; } catch (InterruptedException e) { throw new InternalException("TimeOut"); } finally { for (Peer p : peerTable) { ((IPeer) p).remStateChangeListener(listener); } } if (log.isInfoEnabled()) { log.info("Started {} DIAMETER Stack. Listening on {} ({})", VersionProperties.instance.getProperty("vendor"), getMetaData().getLocalPeer().getUri(), getMetaData().getLocalPeer().getIPAddresses()[0]); } //if } finally { lock.unlock(); } } private void startPeerManager() throws InternalException { try { if (peerManager != null) { peerManager.start(); } getMetaData().unwrap(IMetaData.class).updateLocalHostStateId(); } catch (Exception e) { throw new InternalException(e); } } @Override @SuppressWarnings("unchecked") public void stop(long timeOut, TimeUnit timeUnit, int disconnectCause) throws IllegalDiameterStateException, InternalException { lock.lock(); try { if (state == StackState.STARTED || state == StackState.CONFIGURED) { if (log.isInfoEnabled()) { log.info("(-)(-)(-)(-)(-) Stopping " + VersionProperties.instance.getProperty("vendor") + " DIAMETER Stack v" + VersionProperties.instance.getProperty("version") + " (-)(-)(-)(-)(-)"); } List peerTable = peerManager.getPeerTable(); final CountDownLatch barrier = new CountDownLatch(peerTable.size()); StateChangeListener listener = new AbstractStateChangeListener() { @Override public void stateChanged(Enum oldState, Enum newState) { if (PeerState.DOWN.equals(newState)) { barrier.countDown(); } } }; for (Peer p : peerTable) { if (p.getState(PeerState.class).equals(PeerState.DOWN)) { barrier.countDown(); } else { ((IPeer) p).addStateChangeListener(listener); } } if (peerManager != null) { try { peerManager.stopping(disconnectCause); } catch (Exception e) { log.warn("Stopping error", e); } } try { barrier.await(timeOut, timeUnit); if (barrier.getCount() != 0) { throw new InternalException("TimeOut"); } } catch (InterruptedException e) { throw new InternalException("TimeOut"); } finally { state = StackState.STOPPED; for (Peer p : peerTable) { ((IPeer) p).remStateChangeListener(listener); } } assembler.getComponentInstance(ISessionDatasource.class).stop(); assembler.getComponentInstance(IStatisticProcessor.class).stop(); try { if (peerManager != null) { peerManager.stopped(); } // Clear all timeout tasks if (scheduledFacility != null) { concurrentFactory.shutdownNow(scheduledFacility); } } catch (Exception e) { log.warn("Stopped error", e); } state = StackState.STOPPED; if (log.isInfoEnabled()) { log.info("(-)(-)(-)(-)(-) Stopped " + VersionProperties.instance.getProperty("vendor") + " DIAMETER Stack v" + VersionProperties.instance.getProperty("version") + " (-)(-)(-)(-)(-)"); } } } finally { lock.unlock(); } } @Override public void destroy() { // Be friendly if (state == StackState.STARTED) { log.warn( "Calling destroy() with Stack in STARTED state. Calling stop(REBOOTING) before, please do it yourself with the proper cause."); stop(DisconnectCause.REBOOTING); } lock.lock(); try { if (peerManager != null) { peerManager.destroy(); } if (assembler != null) { assembler.destroy(); } if (scheduledFacility != null) { concurrentFactory.shutdownNow(scheduledFacility); } } catch (Exception e) { log.warn("Destroy error", e); } finally { state = StackState.IDLE; lock.unlock(); } } @Override public boolean isActive() { return state == StackState.STARTED; } @Override public java.util.logging.Logger getLogger() { return java.util.logging.Logger.getAnonymousLogger(); } @Override public MetaData getMetaData() { if (state == StackState.IDLE) { throw new IllegalStateException("Meta data not defined"); } return assembler.getComponentInstance(IMetaData.class); } @Override @SuppressWarnings("unchecked") public T getSession(String sessionId, Class clazz) throws InternalException { if (getState() == StackState.IDLE) { throw new InternalException("Illegal state of stack"); } BaseSession bs = assembler.getComponentInstance(ISessionDatasource.class).getSession(sessionId); return bs != null ? (T) bs : null; } @Override public boolean isWrapperFor(Class aClass) throws InternalException { boolean isWrap = aClass == PeerTable.class; if (!isWrap) { isWrap = assembler.getChilds()[StackLayer.id()].getComponentInstance(aClass) != null; } if (!isWrap) { isWrap = assembler.getChilds()[ControllerLayer.id()].getComponentInstance(aClass) != null; } if (!isWrap) { isWrap = assembler.getChilds()[TransportLayer.id()].getComponentInstance(aClass) != null; } return isWrap; } @Override @SuppressWarnings("unchecked") public T unwrap(Class aClass) throws InternalException { Object unwrapObject = null; if (aClass == PeerTable.class) { unwrapObject = assembler.getComponentInstance(aClass); } // TODO: "layers" should be removed.... if (unwrapObject == null) { unwrapObject = assembler.getChilds()[StackLayer.id()].getComponentInstance(aClass); } if (unwrapObject == null) { unwrapObject = assembler.getChilds()[ControllerLayer.id()].getComponentInstance(aClass); } if (unwrapObject == null) { unwrapObject = assembler.getChilds()[TransportLayer.id()].getComponentInstance(aClass); } return (T) unwrapObject; } // Extended methods @Override public StackState getState() { return state; } @Override public Configuration getConfiguration() { return config; } @Override public IAssembler getAssemblerFacility() { return assembler; } @Override public void sendMessage(IMessage message) throws RouteException, AvpDataException, IllegalDiameterStateException, IOException { peerManager.sendMessage(message); } @Override public void addSessionListener(String sessionId, NetworkReqListener listener) { peerManager.addSessionReqListener(sessionId, listener); } @Override public void removeSessionListener(String sessionId) { peerManager.removeSessionListener(sessionId); } @Override public ScheduledExecutorService getScheduledFacility() { return scheduledFacility; } @Override public IConcurrentFactory getConcurrentFactory() { return this.concurrentFactory; } @Override public String configuration() { return config != null ? config.toString() : "not set"; } @Override public String metaData() { try { return getMetaData().toString(); } catch (Exception exc) { return "not set"; } } @Override public String peerDescription(String name) { try { for (Peer p : unwrap(PeerTable.class).getPeerTable()) { if (p.getUri().getFQDN().equals(name)) { return p.toString(); } } } catch (InternalException e) { log.debug("InternalException", e); } return "not set"; } @Override public String peerList() { try { return unwrap(PeerTable.class).getPeerTable().toString(); } catch (InternalException e) { return "not set"; } } @Override public void stop(int disconnectCause) { try { stop(10, TimeUnit.SECONDS, disconnectCause); } catch (Exception e) { log.debug("Exception", e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/StackImplMBean.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import org.jdiameter.api.InternalException; /** * Stack MBean interface. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface StackImplMBean { /** * Return string representation of stack instanceconfiguration * * @return string representation of stack instance configuration */ String configuration(); /** * Return string representation of stack instance metadata * * @return string representation of stack instance metadata */ String metaData(); /** * Reurn description (include state) of defined peer * * @param name peer host name * * @return description of defined peer */ String peerDescription(String name); /** * Return list of peer * * @return list of peer */ String peerList(); /** * Return true if stack is started * * @return true if stack is started */ boolean isActive(); /** * Run stop procedure */ void stop(int disconnectCause); /** * Run startd procedure * * @throws org.jdiameter.api.IllegalDiameterStateException * @throws InternalException */ void start() throws org.jdiameter.api.IllegalDiameterStateException, InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/VersionProperties.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl; import java.io.InputStream; import java.util.Collections; import java.util.Map; import java.util.Properties; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class VersionProperties { /** * The single instance. */ public static final VersionProperties instance = new VersionProperties(); /** * The version properties. */ private Properties props; /** * Do not allow direct public construction. */ private VersionProperties() { props = loadProperties(); } /** * Returns an unmodifiable map of version properties. * * @return */ public Map getProperties() { return Collections.unmodifiableMap(props); } /** * Returns the value for the given property name. * * @param name - The name of the property. * * @return The property value or null if the property is not set. */ public String getProperty(final String name) { return props.getProperty(name); } /** * Returns the version information as a string. * * @return Basic information as a string. */ @Override public String toString() { StringBuilder sb = new StringBuilder(); boolean first = true; for (Object key : props.keySet()) { if (first) { first = false; } else { sb.append(" , "); } sb.append(key).append(" = ").append(props.get(key)); } return sb.toString(); } /** * Load the version properties from a resource. */ private Properties loadProperties() { props = new Properties(); try { InputStream in = VersionProperties.class.getResourceAsStream("/META-INF/version.properties"); props.load(in); in.close(); } catch (Exception e) { // failed to load version properties. go with defaults props.put("vendor", "Mobicents"); props.put("version", "UN.DEFINED"); } return props; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/annotation/Recoder.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.annotation; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.MetaData; import org.jdiameter.api.Request; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.annotation.AvpDscr; import org.jdiameter.api.annotation.AvpFlag; import org.jdiameter.api.annotation.AvpType; import org.jdiameter.api.annotation.Child; import org.jdiameter.api.annotation.CommandDscr; import org.jdiameter.api.annotation.CommandFlag; import org.jdiameter.api.annotation.Getter; import org.jdiameter.api.annotation.Setter; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.annotation.IRecoder; import org.jdiameter.client.api.annotation.RecoderException; import org.jdiameter.client.impl.RawSessionImpl; import org.jdiameter.client.impl.annotation.internal.ClassInfo; import org.jdiameter.client.impl.annotation.internal.ConstructorInfo; import org.jdiameter.client.impl.annotation.internal.MethodInfo; import org.jdiameter.client.impl.annotation.internal.Storage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Recoder implements IRecoder { // TODO full min/max/position constrains and optimization (caching) private static final Logger log = LoggerFactory.getLogger(Recoder.class); private Storage storage = new Storage(); private final RawSessionImpl rawSession; private final MetaData metaData; public Recoder(SessionFactory factory, MetaData metaData) { this.metaData = metaData; try { this.rawSession = (RawSessionImpl) factory.getNewRawSession(); } catch (InternalException e) { throw new IllegalArgumentException(e); } } // ======================================================================================= //@Override @Override public Message encodeToRequest(Object yourDomainMessageObject, Avp... additionalAvp) throws RecoderException { return encode(yourDomainMessageObject, null, 0, additionalAvp); } //@Override @Override public Message encodeToAnswer(Object yourDomainMessageObject, Request request, long resultCode) throws RecoderException { return encode(yourDomainMessageObject, request, resultCode); } public Message encode(Object yourDomainMessageObject, Request request, long resultCode, Avp... addAvp) throws RecoderException { IMessage message = null; ClassInfo classInfo = storage.getClassInfo(yourDomainMessageObject.getClass()); CommandDscr commandDscr = classInfo.getAnnotation(CommandDscr.class); if (commandDscr != null) { // Get command parameters if (request == null) { message = (IMessage) rawSession.createMessage(commandDscr.code(), ApplicationId.createByAccAppId(0)); message.setRequest(true); message.getAvps().addAvp(addAvp); try { if (message.getAvps().getAvp(Avp.AUTH_APPLICATION_ID) != null) { message.setHeaderApplicationId(message.getAvps().getAvp(Avp.AUTH_APPLICATION_ID).getUnsigned32()); } else if (message.getAvps().getAvp(Avp.ACCT_APPLICATION_ID) != null) { message.setHeaderApplicationId(message.getAvps().getAvp(Avp.ACCT_APPLICATION_ID).getUnsigned32()); } else if (message.getAvps().getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) != null) { message.setHeaderApplicationId(message.getAvps().getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID).getGrouped() .getAvp(Avp.VENDOR_ID).getUnsigned32()); } } catch (Exception exc) { throw new RecoderException(exc); } if (message.getAvps().getAvp(Avp.ORIGIN_HOST) == null) { message.getAvps().addAvp(Avp.ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); } if (message.getAvps().getAvp(Avp.ORIGIN_REALM) == null) { message.getAvps().addAvp(Avp.ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); } } else { message = (IMessage) request.createAnswer(resultCode); } for (CommandFlag f : commandDscr.flags()) { switch (f) { case E: message.setError(true); break; case P: message.setProxiable(true); break; case R: message.setRequest(true); break; case T: message.setReTransmitted(true); break; } } // Find top level avp in getter-annotation methods Map chMap = getChildInstance(yourDomainMessageObject, classInfo, null); // Fill for (Child ch : commandDscr.childs()) { fillChild(message.getAvps(), ch, chMap); } } else { log.debug("Can not found annotation for object {}", yourDomainMessageObject); } return message; } private Map getChildInstance(Object yourDomainMessageObject, ClassInfo c, Map chMap) throws RecoderException { if (chMap == null) { chMap = new HashMap(); } for (MethodInfo mi : c.getMethodsInfo()) { if (mi.getAnnotation(Getter.class) != null) { try { Object value = mi.getMethod().invoke(yourDomainMessageObject); if (value != null) { Class mc = value.getClass().isArray() ? value.getClass().getComponentType() : value.getClass(); chMap.put(mc.getName(), value); for (Class i : mc.getInterfaces()) { chMap.put(i.getName(), value); } } } catch (IllegalAccessException e) { throw new RecoderException(e); } catch (InvocationTargetException e) { throw new RecoderException(e); } } } return chMap; } private void fillChild(AvpSet as, Child ci, Map childs) throws RecoderException { Object c = childs.get(ci.ref().getName()); if (c != null) { ClassInfo cc = storage.getClassInfo(ci.ref()); AvpDscr ad = cc.getAnnotation(AvpDscr.class); if (ad != null) { boolean m = false, p = false; // cast <=> getter for primitive switch (ad.type()) { case Integer32: case Enumerated: { for (AvpFlag f : ad.must()) { if (AvpFlag.M.equals(f)) { m = true; } else if (AvpFlag.P.equals(f)) { p = true; } } // find in getter Collection cv = getValue(c, Integer.class); for (Integer v : cv) { as.addAvp(ad.code(), v, ad.vendorId(), m, p); } } break; case Unsigned32: { for (AvpFlag f : ad.must()) { if (AvpFlag.M.equals(f)) { m = true; } else if (AvpFlag.P.equals(f)) { p = true; } } Collection cv = getValue(c, Long.class); for (Long v : cv) { as.addAvp(ad.code(), v, ad.vendorId(), m, p, true); } } break; case Unsigned64: case Integer64: { for (AvpFlag f : ad.must()) { if (AvpFlag.M.equals(f)) { m = true; } else if (AvpFlag.P.equals(f)) { p = true; } } Collection cv = getValue(c, Long.class); for (Long v : cv) { as.addAvp(ad.code(), v, ad.vendorId(), m, p); } } break; case Float32: { for (AvpFlag f : ad.must()) { if (AvpFlag.M.equals(f)) { m = true; } else if (AvpFlag.P.equals(f)) { p = true; } } Collection cv = getValue(c, Float.class); for (Float v : cv) { as.addAvp(ad.code(), v, ad.vendorId(), m, p); } } break; case Float64: { for (AvpFlag f : ad.must()) { if (AvpFlag.M.equals(f)) { m = true; } else if (AvpFlag.P.equals(f)) { p = true; } } Collection cv = getValue(c, Double.class); for (Double v : cv) { as.addAvp(ad.code(), v, ad.vendorId(), m, p); } } break; case OctetString: case Address: case Time: case DiameterIdentity: case DiameterURI: case IPFilterRule: case QoSFilterRule: { for (AvpFlag f : ad.must()) { if (AvpFlag.M.equals(f)) { m = true; } else if (AvpFlag.P.equals(f)) { p = true; } } Collection cv = getValue(c, String.class); for (String v : cv) { as.addAvp(ad.code(), v, ad.vendorId(), m, p, true); } } break; case UTF8String: { for (AvpFlag f : ad.must()) { if (AvpFlag.M.equals(f)) { m = true; } else if (AvpFlag.P.equals(f)) { p = true; } } Collection cv = getValue(c, String.class); for (String v : cv) { as.addAvp(ad.code(), v, ad.vendorId(), m, p, false); } } break; case Grouped: { for (AvpFlag f : ad.must()) { if (AvpFlag.M.equals(f)) { m = true; } else if (AvpFlag.P.equals(f)) { p = true; } } Collection cv = new ArrayList(); if (c.getClass().isArray()) { cv = Arrays.asList((Object[]) c); } else { cv.add(c); } for (Object cj : cv) { AvpSet las = as.addGroupedAvp(ad.code(), ad.vendorId(), m, p); Map lchilds = getChildInstance(cj, storage.getClassInfo(cj.getClass()), null); for (Child lci : ad.childs()) { fillChild(las, lci, lchilds); } } } break; } } } } private Collection getValue(Object ic, Class type) throws RecoderException { Collection rc = new ArrayList(); Object[] xc = null; if (ic.getClass().isArray()) { xc = (Object[]) ic; } else { xc = new Object[] { ic }; } for (Object c : xc) { for (MethodInfo lm : storage.getClassInfo(c.getClass()).getMethodsInfo()) { if (lm.getAnnotation(Getter.class) != null) { try { rc.add((T) lm.getMethod().invoke(c)); } catch (IllegalAccessException e) { throw new RecoderException(e); } catch (InvocationTargetException e) { throw new RecoderException(e); } } } } return rc; } // ======================================================================================= @Override public T decode(Message message, java.lang.Class yourDomainMessageObject) throws RecoderException { Object rc = null; ClassInfo c = storage.getClassInfo(yourDomainMessageObject); CommandDscr cd = c.getAnnotation(CommandDscr.class); if (cd != null) { try { if (message.getCommandCode() != cd.code()) { throw new IllegalArgumentException("Invalid message code " + message.getCommandCode()); } if (message.getApplicationId() != 0 && message.getApplicationId() != cd.appId()) { throw new IllegalArgumentException("Invalid Application-Id " + message.getApplicationId()); } for (CommandFlag f : cd.flags()) { switch (f) { case E: if (!message.isError()) { throw new IllegalArgumentException("Flag e is not set"); } break; case P: if (!message.isProxiable()) { throw new IllegalArgumentException("Flag p is not set"); } break; case R: if (!message.isRequest()) { throw new IllegalArgumentException("Flag m is not set"); } break; case T: if (!message.isReTransmitted()) { throw new IllegalArgumentException("Flag t is not set"); } break; } } // Find max constructor + lost avp set by setters int cacount = 0; Constructor cm = null; Map> cmargs = new HashMap>(); for (ConstructorInfo ci : c.getConstructorsInfo()) { if (ci.getAnnotation(Setter.class) != null) { // check params - all params must have avp annotation Class[] params = ci.getConstructor().getParameterTypes(); boolean correct = true; for (Class j : params) { if (j.isArray()) { j = j.getComponentType(); } if (storage.getClassInfo(j).getAnnotation(AvpDscr.class) == null) { correct = false; break; } } if (!correct) { continue; } // find max args constructor if (cacount < params.length) { cacount = params.length; cm = ci.getConstructor(); } } } // fill cm args List initargs = new ArrayList(); if (cm != null) { for (Class ac : cm.getParameterTypes()) { Class lac = ac.isArray() ? ac.getComponentType() : ac; cmargs.put(lac.getName(), ac); // Create params initargs.add(createChildByAvp(findChildDscr(cd.childs(), ac), ac, message.getAvps())); } // Create instance class rc = cm.newInstance(initargs.toArray()); } else { rc = yourDomainMessageObject.newInstance(); } // for (MethodInfo mi : c.getMethodsInfo()) { if (mi.getAnnotation(Setter.class) != null) { Class[] pt = mi.getMethod().getParameterTypes(); if (pt.length == 1 && storage.getClassInfo(pt[0]).getAnnotation(AvpDscr.class) != null) { Class ptc = pt[0].isArray() ? pt[0].getComponentType() : pt[0]; if (!cmargs.containsKey(ptc.getName())) { cmargs.put(ptc.getName(), ptc); mi.getMethod().invoke(rc, createChildByAvp(findChildDscr(cd.childs(), pt[0]), pt[0], message.getAvps())); } } } } // Fill undefined avp setUndefinedAvp(message.getAvps(), rc, c, cmargs); } catch (InstantiationException e) { throw new RecoderException(e); } catch (InvocationTargetException e) { throw new RecoderException(e); } catch (IllegalAccessException e) { throw new RecoderException(e); } } return (T) rc; } private void setUndefinedAvp(AvpSet set, Object rc, ClassInfo c, Map> cmargs) throws RecoderException { try { for (MethodInfo mi : c.getMethodsInfo()) { Setter s = mi.getAnnotation(Setter.class); if (s != null && Setter.Type.UNDEFINED.equals(s.value())) { Map known = new HashMap(); for (Class argc : cmargs.values()) { AvpDscr argd = storage.getClassInfo((argc.isArray() ? argc.getComponentType() : argc)) .getAnnotation(AvpDscr.class); known.put(argd.code(), argd.code()); } for (Avp a : set) { if (!known.containsKey(a.getCode())) { mi.getMethod().invoke(rc, new UnknownAvp(a.getCode(), a.isMandatory(), a.isVendorId(), a.isEncrypted(), a.getVendorId(), a.getRaw())); } } break; } } } catch (IllegalAccessException e) { throw new RecoderException(e); } catch (InvocationTargetException e) { throw new RecoderException(e); } catch (AvpDataException e) { throw new RecoderException(e); } } private Child findChildDscr(Child[] childs, Class m) { for (Child c : childs) { Class t = c.ref(); m = m.isArray() ? m.getComponentType() : m; if (m == t) { return c; } if (m.getSuperclass() == t) { return c; } for (Class i : m.getInterfaces()) { if (i == t) { return c; } } } return null; } private Object createChildByAvp(Child mInfo, Class m, AvpSet parentSet) throws RecoderException { Object rc; AvpDscr ad = storage.getClassInfo((m.isArray() ? m.getComponentType() : m)).getAnnotation(AvpDscr.class); Avp av = parentSet.getAvp(ad.code()); if (av != null) { for (AvpFlag i : ad.must()) { switch (i) { case M: if (!av.isMandatory()) { throw new IllegalArgumentException("not set flag M"); } break; case V: if (!av.isVendorId()) { throw new IllegalArgumentException("not set flag V"); } break; case P: if (!av.isEncrypted()) { throw new IllegalArgumentException("not set flag P"); } break; } } } else { if (mInfo.min() > 0) { throw new IllegalArgumentException("Avp " + ad.code() + " is mandatory"); } } if (AvpType.Grouped.equals(ad.type())) { if (m.isArray()) { Class arrayClass = m.getComponentType(); AvpSet as = parentSet.getAvps(ad.code()); Object[] array = (Object[]) java.lang.reflect.Array.newInstance(arrayClass, as.size()); for (int ii = 0; ii < array.length; ii++) { array[ii] = newInstanceGroupedAvp(arrayClass, ad, as.getAvpByIndex(ii)); } rc = array; } else { rc = newInstanceGroupedAvp(m, ad, parentSet.getAvp(ad.code())); } } else { if (m.isArray()) { Class arrayClass = m.getComponentType(); AvpSet as = parentSet.getAvps(ad.code()); Object[] array = (Object[]) java.lang.reflect.Array.newInstance(arrayClass, as.size()); for (int ii = 0; ii < array.length; ii++) { array[ii] = newInstanceSimpleAvp(arrayClass, ad, as.getAvpByIndex(ii)); } rc = array; } else { rc = newInstanceSimpleAvp(m, ad, parentSet.getAvp(ad.code())); } } // ========= return rc; } private Object newInstanceGroupedAvp(Class m, AvpDscr ad, Avp avp) throws RecoderException { Object rc; int cacount = 0; ClassInfo c = storage.getClassInfo(m); Constructor cm = null; Map> cmargs = new HashMap>(); for (ConstructorInfo ci : c.getConstructorsInfo()) { if (ci.getAnnotation(Setter.class) != null) { // check params - all params must have avp annotation Class[] params = ci.getConstructor().getParameterTypes(); boolean correct = true; for (Class j : params) { if (j.isArray()) { j = j.getComponentType(); } if (storage.getClassInfo(j).getAnnotation(AvpDscr.class) == null) { correct = false; break; } } if (!correct) { continue; } // find max args constructor if (cacount < params.length) { cacount = params.length; cm = ci.getConstructor(); } } } // fill cm args try { List initargs = new ArrayList(); if (cm != null) { for (Class ac : cm.getParameterTypes()) { Class lac = ac.isArray() ? ac.getComponentType() : ac; cmargs.put(lac.getName(), ac); // Create params initargs.add(createChildByAvp(findChildDscr(ad.childs(), ac), ac, avp.getGrouped())); } // Create instance class rc = cm.newInstance(initargs.toArray()); } else { rc = m.newInstance(); } // for (MethodInfo mi : c.getMethodsInfo()) { if (mi.getAnnotation(Setter.class) != null) { Class[] pt = mi.getMethod().getParameterTypes(); if (pt.length == 1 && storage.getClassInfo(pt[0]).getAnnotation(AvpDscr.class) != null) { Class ptc = pt[0].isArray() ? pt[0].getComponentType() : pt[0]; if (!cmargs.containsKey(ptc.getName())) { cmargs.put(ptc.getName(), ptc); mi.getMethod().invoke(rc, createChildByAvp(findChildDscr(ad.childs(), pt[0]), pt[0], avp.getGrouped())); } } } } // Fill undefined child setUndefinedAvp(avp.getGrouped(), rc, c, cmargs); } catch (InstantiationException e) { throw new RecoderException(e); } catch (InvocationTargetException e) { throw new RecoderException(e); } catch (AvpDataException e) { throw new RecoderException(e); } catch (IllegalAccessException e) { throw new RecoderException(e); } return rc; } private Object newInstanceSimpleAvp(Class m, AvpDscr ad, Avp avp) { Object rc = null; if (avp == null) { return null; } ClassInfo c = storage.getClassInfo(m); try { for (ConstructorInfo ci : c.getConstructorsInfo()) { if (ci.getConstructor().getParameterTypes().length == 1 && ci.getAnnotation(Setter.class) != null) { List args = new ArrayList(); if (ci.getConstructor().getParameterTypes()[0].isArray()) { args.add(getValue(ad.type(), avp)); } else { args.add(getValue(ad.type(), avp)); } rc = ci.getConstructor().newInstance(args.toArray()); } } if (rc == null) { rc = m.newInstance(); for (MethodInfo mi : c.getMethodsInfo()) { if (mi.getAnnotation(Setter.class) != null) { List args = new ArrayList(); if (mi.getMethod().getParameterTypes()[0].isArray()) { args.add(getValue(ad.type(), avp)); } else { args.add(getValue(ad.type(), avp)); } mi.getMethod().invoke(rc, args); } } } } catch (InstantiationException e) { throw new RecoderException(e); } catch (InvocationTargetException e) { throw new RecoderException(e); } catch (AvpDataException e) { throw new RecoderException(e); } catch (IllegalAccessException e) { throw new RecoderException(e); } return rc; } private Object getValue(AvpType type, Avp avp) throws AvpDataException { switch (type) { case Integer32: case Enumerated: return avp.getInteger32(); case Unsigned32: return avp.getUnsigned32(); case Unsigned64: case Integer64: return avp.getInteger64(); case Float32: return avp.getFloat32(); case Float64: return avp.getFloat64(); case OctetString: case Address: case Time: case DiameterIdentity: case DiameterURI: case IPFilterRule: case QoSFilterRule: return avp.getOctetString(); case UTF8String: return avp.getUTF8String(); } return null; } // ======================================================================================= } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/annotation/UnknownAvp.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.annotation; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class UnknownAvp extends Value { private int code; boolean m, v, p; private long vendorId; public UnknownAvp(int code, boolean m, boolean v, boolean p, long vendorId, byte[] value) { super(value); this.code = code; this.m = m; this.v = v; this.p = p; this.vendorId = vendorId; } public int getCode() { return code; } public boolean isMandatory() { return m; } public boolean isVendorSpecific() { return v; } public long getVendorId() { return vendorId; } public boolean isProxiable() { return p; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/annotation/Value.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.annotation; import org.jdiameter.api.annotation.Getter; import org.jdiameter.api.annotation.Setter; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public abstract class Value { protected T value; @Setter public Value(T value) { this.value = value; } @Getter public T get() { return value; } @Override public String toString() { return "Value{" + "value=" + value + "}"; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/annotation/internal/ClassInfo.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.annotation.internal; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") public class ClassInfo { private Storage storage; private Class _class; private Map, Annotation> annotations; private Map methods; private Map constructors; private Collection classCache; private Collection methodCache; private Collection constructorCache; public ClassInfo(Storage storage, Class _class) { this.storage = storage; this._class = _class; } public Class getAttachedClass() { return _class; } public Collection getAnnotations() { if (classCache == null) { if (annotations == null) { annotations = new ConcurrentHashMap, Annotation>(); final Class parent = getAttachedClass().getSuperclass(); if (parent != null) { addAnnotations(parent); } for (Class i : getAttachedClass().getInterfaces()) { addAnnotations(i); } for (Annotation a : getAttachedClass().getDeclaredAnnotations()) { annotations.put(a.getClass().getInterfaces()[0], a); } } classCache = annotations.values(); } return classCache; } public T getAnnotation(Class annotation) { for (Annotation a : getAnnotations()) { if (a.annotationType() == annotation) { return (T) a; } } return null; } private void addAnnotations(Class _class) { for (Annotation annotation : storage.getClassInfo(_class).getAnnotations()) { if (annotation != null) { for (Class _interface : annotation.getClass().getInterfaces()) { annotations.put(_interface, annotation); } } } } public MethodInfo getMethodInfo(String methodName, Class... args) { try { return getMethodInfo(getAttachedClass().getMethod(methodName, args)); } catch (Exception e) { return null; } } public ConstructorInfo getConstructorInfo(Class... args) { try { return getConstructorInfo(getAttachedClass().getConstructor(args)); } catch (Exception e1) { // may be generic try { return getConstructorInfo(getAttachedClass().getConstructor(Object.class)); } catch (Exception e2) { } return null; } } public MethodInfo getMethodInfo(Method method) { return getMethodMap().get(method); } public ConstructorInfo getConstructorInfo(Constructor constr) { return getConstructorMap().get(constr); } public Collection getMethodsInfo() { return methodCache == null ? (methodCache = getMethodMap().values()) : methodCache; } public Collection getConstructorsInfo() { return constructorCache == null ? (constructorCache = getConstructorMap().values()) : constructorCache; } private Map getMethodMap() { if (methods == null) { methods = new ConcurrentHashMap(); for (Method method : getAttachedClass().getMethods()) { methods.put(method, new MethodInfo(storage, this, method)); } } return methods; } private Map getConstructorMap() { if (constructors == null) { constructors = new ConcurrentHashMap(); for (Constructor constr : getAttachedClass().getConstructors()) { constructors.put(constr, new ConstructorInfo(storage, this, constr)); } } return constructors; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/annotation/internal/ConstructorInfo.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.annotation.internal; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ConstructorInfo { private Storage storage; private Constructor constr; private ClassInfo classInfo; private Collection annotationsCache; private Map, Annotation> annotationStorage; public ConstructorInfo(Storage storage, ClassInfo classInfo, Constructor constr) { this.storage = storage; this.classInfo = classInfo; this.constr = constr; } public Constructor getConstructor() { return constr; } public ClassInfo getClassInfo() { return classInfo; } public Collection getAnnotations() { return annotationsCache == null ? (annotationsCache = getAnnotationStorage().values()) : annotationsCache; } private Map, Annotation> getAnnotationStorage() { if (annotationStorage == null) { annotationStorage = new ConcurrentHashMap, Annotation>(); Class parent = getClassInfo().getAttachedClass().getSuperclass(); if (parent != null) { addAnnotations(storage.getClassInfo(parent).getConstructorInfo(getConstructor().getParameterTypes())); } for (Class i : getClassInfo().getAttachedClass().getInterfaces()) { addAnnotations(storage.getClassInfo(i).getConstructorInfo(getConstructor().getParameterTypes())); } for (Annotation a : getConstructor().getDeclaredAnnotations()) { annotationStorage.put(a.getClass().getInterfaces()[0], a); } } return annotationStorage; } private void addAnnotations(ConstructorInfo constr) { if (constr != null) { for (Annotation annotation : constr.getAnnotations()) { if (annotation != null) { for (Class _interface : annotation.getClass().getInterfaces()) { annotationStorage.put(_interface, annotation); // [0] } } } } } public T getAnnotation(Class annotation) { for (Annotation a : getAnnotations()) { if (a.annotationType() == annotation) { return (T) a; } } return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/annotation/internal/MethodInfo.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.annotation.internal; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") public class MethodInfo { private Storage storage; private Method method; private ClassInfo classInfo; private Collection annotationsCache; private Map, Annotation> annotationStorage; public MethodInfo(Storage storage, ClassInfo classInfo, Method method) { this.storage = storage; this.classInfo = classInfo; this.method = method; } public Method getMethod() { return method; } public ClassInfo getClassInfo() { return classInfo; } public Collection getAnnotations() { return annotationsCache == null ? (annotationsCache = getAnnotationStorage().values()) : annotationsCache; } public T getAnnotation(Class annotation) { for (Annotation a : getAnnotations()) { if (a.annotationType() == annotation) { return (T) a; } } return null; } private Map, Annotation> getAnnotationStorage() { if (annotationStorage == null) { annotationStorage = new ConcurrentHashMap, Annotation>(); Class parent = getClassInfo().getAttachedClass().getSuperclass(); if (parent != null) { addAnnotations( storage.getClassInfo(parent).getMethodInfo(getMethod().getName(), getMethod().getParameterTypes())); } for (Class i : getClassInfo().getAttachedClass().getInterfaces()) { addAnnotations(storage.getClassInfo(i).getMethodInfo(getMethod().getName(), getMethod().getParameterTypes())); } for (Annotation a : getMethod().getDeclaredAnnotations()) { annotationStorage.put(a.getClass().getInterfaces()[0], a); } } return annotationStorage; } private void addAnnotations(MethodInfo method) { if (method != null) { for (Annotation annotation : method.getAnnotations()) { if (annotation != null) { for (Class _interface : annotation.getClass().getInterfaces()) { annotationStorage.put(_interface, annotation); // [0] } } } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/annotation/internal/Storage.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.annotation.internal; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Storage { private Map, ClassInfo> annotations = new ConcurrentHashMap, ClassInfo>(); public final synchronized ClassInfo getClassInfo(Class _class) { ClassInfo info = annotations.get(_class); if (info == null) { info = new ClassInfo(this, _class); annotations.put(_class, info); } return info; } public final synchronized void clear() { annotations.clear(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/acc/ClientAccSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.acc; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.acc.ClientAccSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientAccSessionDataLocalImpl extends AppSessionDataLocalImpl implements IClientAccSessionData { protected ClientAccSessionState state = ClientAccSessionState.IDLE; protected Request buffer; protected String destRealm; protected String destHost; protected Serializable tid; /** * */ public ClientAccSessionDataLocalImpl() { } @Override public void setClientAccSessionState(ClientAccSessionState state) { this.state = state; } @Override public ClientAccSessionState getClientAccSessionState() { return this.state; } @Override public void setInterimTimerId(Serializable tid) { this.tid = tid; } @Override public Serializable getInterimTimerId() { return this.tid; } @Override public void setDestinationHost(String destHost) { this.destHost = destHost; } @Override public String getDestinationHost() { return this.destHost; } @Override public void setDestinationRealm(String destRealm) { this.destRealm = destRealm; } @Override public String getDestinationRealm() { return this.destRealm; } @Override public void setBuffer(Request event) { this.buffer = event; } @Override public Request getBuffer() { return this.buffer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/acc/ClientAccSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.acc; import org.jdiameter.api.*; import org.jdiameter.api.acc.ClientAccSession; import org.jdiameter.api.acc.ClientAccSessionListener; import org.jdiameter.api.acc.events.AccountAnswer; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.acc.ClientAccSessionState; import org.jdiameter.common.api.app.acc.IClientAccActionContext; import org.jdiameter.common.impl.app.AppEventImpl; import org.jdiameter.common.impl.app.acc.AppAccSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import static org.jdiameter.api.Avp.ACCOUNTING_REALTIME_REQUIRED; import static org.jdiameter.common.api.app.acc.ClientAccSessionState.*; /** * Client Accounting session implementation * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientAccSessionImpl extends AppAccSessionImpl implements EventListener, ClientAccSession { private static final Logger logger = LoggerFactory.getLogger(ClientAccSessionImpl.class); // Constants ---------------------------------------------------------------- public static final int DELIVER_AND_GRANT = 1; public static final int GRANT_AND_LOSE = 3; // Session State Handling --------------------------------------------------- //protected ClientAccSessionState state = IDLE; // Factories and Listeners -------------------------------------------------- protected IClientAccActionContext context; protected ClientAccSessionListener listener; //protected transient IMessageParser parser; //protected Serializable timerId_interim; protected static final String TIMER_NAME_INTERIM = "CLIENT_INTERIM"; //protected String destHost, destRealm; //protected AccountRequest buffer; protected IClientAccSessionData sessionData; public ClientAccSessionImpl(IClientAccSessionData sessionData, ISessionFactory sessionFactory, ClientAccSessionListener clientAccSessionListener, IClientAccActionContext iClientAccActionContext, StateChangeListener stateChangeListener) { super(sessionFactory, sessionData); this.sessionData = sessionData; this.listener = clientAccSessionListener; this.context = iClientAccActionContext; super.addStateChangeNotification(stateChangeListener); } public void setListener(ClientAccSessionListener listener) { this.listener = listener; } @Override public void sendAccountRequest(AccountRequest accountRequest) throws InternalException, IllegalStateException, RouteException, OverloadException { try { sendAndStateLock.lock(); handleEvent(new Event(accountRequest)); try { session.send(accountRequest.getMessage(), this); // Store last destination information sessionData.setDestinationRealm( accountRequest.getMessage().getAvps().getAvp(Avp.DESTINATION_REALM).getDiameterIdentity()); Avp destHostAvp = accountRequest.getMessage().getAvps().getAvp(Avp.DESTINATION_HOST); if (destHostAvp != null) { sessionData.setDestinationHost(destHostAvp.getDiameterIdentity()); } } catch (Throwable t) { logger.debug("Failed to send ACR.", t); handleEvent(new Event(Event.Type.FAILED_SEND_RECORD, accountRequest)); } } catch (Exception exc) { throw new InternalException(exc); } finally { sendAndStateLock.unlock(); } } protected synchronized void storeToBuffer(Request accountRequest) { sessionData.setBuffer(accountRequest); } protected synchronized boolean checkBufferSpace() { //TODO: make this different op, so it does not have to fetch data. return sessionData.getBuffer() == null; } @SuppressWarnings("unchecked") protected void setState(IAppSessionState newState) { IAppSessionState oldState = sessionData.getClientAccSessionState(); sessionData.setClientAccSessionState((ClientAccSessionState) newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } } @Override public boolean isStateless() { return false; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { ClientAccSessionState oldState = sessionData.getClientAccSessionState(); try { switch (oldState) { // Idle ========== case IDLE: { switch ((Event.Type) event.getType()) { // Client or device requests access case SEND_START_RECORD: // Current State: IDLE // Event: Client or Device Requests access // Action: Send accounting start req. // New State: PENDING_S setState(PENDING_START); break; case SEND_EVENT_RECORD: // Current State: IDLE // Event: Client or device requests a one-time service // Action: Send accounting event req // New State: PENDING_E setState(PENDING_EVENT); break; // Send buffered message action in other section of this method see below default: throw new IllegalStateException("Current state " + oldState + " action " + event.getType()); } break; } // PendingS ========== case PENDING_START: { switch ((Event.Type) event.getType()) { case FAILED_SEND_RECORD: AccountRequest request = (AccountRequest) event.getData(); Avp accRtReq = request.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED); // Current State: PENDING_S // Event: Failure to send and buffer space available and realtime not equal to DELIVER_AND_GRANT // Action: Store Start Record // New State: OPEN if (checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != DELIVER_AND_GRANT) { //... cast overkill... storeToBuffer((Request) ((AppEventImpl) request).getMessage()); setState(OPEN); } else { // Current State: PENDING_S // Event: Failure to send and no buffer space available and realtime equal to GRANT_AND_LOSE // Action: - // New State: OPEN if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) { setState(OPEN); } else { // Current State: PENDING_S // Event: Failure to send and no buffer space available and realtime not equal to GRANT_AND_LOSE // Action: Disconnect User/Device // New State: IDLE if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) { try { if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(IDLE); } } } } break; case RECEIVED_RECORD: // Current State: PENDING_S // Event: Successful accounting start answer received // Action: - // New State: OPEN processInterimIntervalAvp(event); setState(OPEN); break; case FAILED_RECEIVE_RECORD: try { AccountAnswer answer = (AccountAnswer) event.getData(); accRtReq = answer.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED); // Current State: PENDING_S // Event: Failed accounting start answer received and realtime equal to GRANT_AND_LOSE // Action: - // New State: OPEN if (accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) { setState(OPEN); } else { // Current State: PENDING_S // Event: Failed accounting start answer received and realtime not equal to GRANT_AND_LOSE // Action: Disconnect User/Device // New State: IDLE if (accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) { try { if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(IDLE); } } } } catch (Exception e) { logger.debug("Can not process answer", e); setState(IDLE); } break; case SEND_STOP_RECORD: // Current State: PENDING_S // Event: User service terminated // Action: Store stop record // New State: PENDING_S if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); storeToBuffer(str); } break; } break; } // OPEN ========== case OPEN: { switch ((Event.Type) event.getType()) { // User service terminated case SEND_STOP_RECORD: // Current State: OPEN // Event: User service terminated // Action: Send accounting stop request // New State: PENDING_L setState(PENDING_CLOSE); break; case SEND_INTERIM_RECORD: // FIXME: Shouldn't this be different ? // Current State: OPEN // Event: Interim interval elapses // Action: Send accounting interim record // New State: PENDING_I setState(PENDING_INTERIM); break; // Create timer for "Interim interval elapses" event case RECEIVED_RECORD: processInterimIntervalAvp(event); break; } } break; //FIXME: add check for abnormal // PendingI ========== case PENDING_INTERIM: { switch ((Event.Type) event.getType()) { case RECEIVED_RECORD: // Current State: PENDING_I // Event: Successful accounting interim answer received // Action: - // New State: OPEN processInterimIntervalAvp(event); setState(OPEN); break; case FAILED_SEND_RECORD: AccountRequest request = (AccountRequest) event.getData(); Avp accRtReq = request.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED); // Current State: PENDING_I // Event: Failure to send and buffer space available (or old record interim can be overwritten) and realtime not equal to DELIVER_AND_GRANT // Action: Store interim record // New State: OPEN if (checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != DELIVER_AND_GRANT) { //... cast overkill... storeToBuffer((Request) ((AppEventImpl) request).getMessage()); setState(OPEN); } else { // Current State: PENDING_I // Event: Failure to send and no buffer space available and realtime equal to GRANT_AND_LOSE // Action: - // New State: OPEN if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) { setState(OPEN); } else { // Current State: PENDING_I // Event: Failure to send and no buffer space available and realtime not equal to GRANT_AND_LOSE // Action: Disconnect User/Device // New State: IDLE if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) { try { if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(IDLE); } } } } break; case FAILED_RECEIVE_RECORD: try { AccountAnswer answer = (AccountAnswer) event.getData(); accRtReq = answer.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED); // Current State: PENDING_I // Event: Failed accounting interim answer received and realtime equal to GRANT_AND_LOSE // Action: - // New State: OPEN if (accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) { setState(OPEN); } else { // Current State: PENDING_I // Event: Failed account interim answer received and realtime not equal to GRANT_AND_LOSE // Action: Disconnect User/Device // New State: IDLE if (accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) { try { if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(IDLE); } } } } catch (Exception e) { logger.debug("Can not process received request", e); setState(IDLE); } break; case SEND_STOP_RECORD: // Current State: PENDING_I // Event: User service terminated // Action: Store stop record // New State: PENDING_I if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); storeToBuffer(str); } break; } break; } // PendingE ========== case PENDING_EVENT: { switch ((Event.Type) event.getType()) { case RECEIVED_RECORD: // Current State: PENDING_E // Event: Successful accounting event answer received // Action: - // New State: IDLE setState(IDLE); break; case FAILED_SEND_RECORD: if (checkBufferSpace()) { // Current State: PENDING_E // Event: Failure to send and buffer space available // Action: Store event record // New State: IDLE AccountRequest data = (AccountRequest) event.getData(); //... cast overkill... storeToBuffer((Request) ((AppEventImpl) data).getMessage()); } // Current State: PENDING_E // Event: Failure to send and no buffer space available // Action: - // New State: IDLE setState(IDLE); break; case FAILED_RECEIVE_RECORD: // Current State: PENDING_E // Event: Failed accounting event answer received // Action: - // New State: IDLE setState(IDLE); break; } break; } // PendingB ========== case PENDING_BUFFERED: { switch ((Event.Type) event.getType()) { case RECEIVED_RECORD: // Current State: PENDING_B // Event: Successful accounting answer received // Action: Delete record // New State: IDLE synchronized (this) { storeToBuffer(null); } setState(IDLE); break; // Failure to send case FAILED_SEND_RECORD: // Current State: PENDING_B // Event: Failure to send // Action: - // New State: IDLE setState(IDLE); break; // Failed accounting answer received case FAILED_RECEIVE_RECORD: // Current State: PENDING_B // Event: Failed accounting answer received // Action: Delete record // New State: IDLE synchronized (this) { storeToBuffer(null); } setState(IDLE); break; } break; } // PendingL ========== case PENDING_CLOSE: { switch ((Event.Type) event.getType()) { case RECEIVED_RECORD: // Current State: PENDING_L // Event: Successful accounting stop answer received // Action: - // New State: IDLE setState(IDLE); break; case FAILED_SEND_RECORD: if (checkBufferSpace()) { // Current State: PENDING_L // Event: Failure to send and buffer space available // Action: Store stop record // New State: IDLE AccountRequest data = (AccountRequest) event.getData(); //... cast overkill... storeToBuffer((Request) ((AppEventImpl) data).getMessage()); } // Current State: PENDING_L // Event: Failure to send and no buffer space available // Action: - // New State: IDLE setState(IDLE); break; // Failed accounting stop answer received case FAILED_RECEIVE_RECORD: // Current State: PENDING_L // Event: Failed accounting stop answer received // Action: - // New State: IDLE setState(IDLE); break; } break; } } ClientAccSessionState state = sessionData.getClientAccSessionState(); // Post processing if (oldState != state) { switch (state) { // IDLE =========== case IDLE: { // Current State: IDLE // Event: Records in storage // Action: Send record // New State: PENDING_B try { synchronized (this) { if (!checkBufferSpace()) { session.send(sessionData.getBuffer(), this); setState(PENDING_BUFFERED); } } } catch (Exception e) { logger.debug("can not send buffered message", e); synchronized (this) { if (context != null && !checkBufferSpace()) { if (!context.failedSendRecord(this, sessionData.getBuffer())) { storeToBuffer(null); } } } } } } } } catch (Throwable t) { throw new InternalException(t); } return true; } protected void processInterimIntervalAvp(StateEvent event) throws InternalException { // Avp interval = ((AppEvent) event.getData()).getMessage().getAvps().getAvp(Avp.ACCT_INTERIM_INTERVAL); // if (interval != null) { // // create timer // try { // long v = interval.getUnsigned32(); // if (v != 0) { // // scheduler.schedule( // // new Runnable() { // // public void run() { // // if (context != null) { // // try { // // Request interimRecord = createInterimRecord(); // // context.interimIntervalElapses(interimRecord); // // sendAndStateLock.lock(); // // session.send(interimRecord, ClientAccSessionImpl.this); // // setState(PENDING_INTERIM); // // } // // catch (Exception e) { // // logger.debug("Can not process Interim Interval AVP", e); // // } // // finally { // // sendAndStateLock.unlock(); // // } // // } // // } // // }, // // v, TimeUnit.SECONDS // // ); // cancelInterimTimer(); // this.timerId_interim = startInterimTimer(v); // } // } // catch (AvpDataException e) { // logger.debug("Unable to retrieve Acct-Interim-Interval AVP value", e); // } // } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TIMER_NAME_INTERIM)) { if (context != null) { try { Request interimRecord = createInterimRecord(); context.interimIntervalElapses(this, interimRecord); sendAndStateLock.lock(); session.send(interimRecord, ClientAccSessionImpl.this); setState(PENDING_INTERIM); sessionData.setInterimTimerId(null); } catch (Exception e) { logger.debug("Can not process Interim Interval AVP", e); } finally { sendAndStateLock.unlock(); } } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } private Serializable startInterimTimer(long v) { try { sendAndStateLock.lock(); Serializable interimTimerId = super.timerFacility.schedule(sessionData.getSessionId(), TIMER_NAME_INTERIM, v); sessionData.setInterimTimerId(interimTimerId); return interimTimerId; } finally { sendAndStateLock.unlock(); } } private void cancelInterimTimer() { try { sendAndStateLock.lock(); Serializable interimTimerId = sessionData.getInterimTimerId(); if (interimTimerId != null) { super.timerFacility.cancel(interimTimerId); sessionData.setInterimTimerId(null); } } finally { sendAndStateLock.unlock(); } } @Override @SuppressWarnings("unchecked") public E getState(Class eClass) { return eClass == ClientAccSessionState.class ? (E) sessionData.getClientAccSessionState() : null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { if (request.getCommandCode() == AccountRequest.code) { // state should be changed before event listener call try { sendAndStateLock.lock(); handleEvent(new Event(createAccountAnswer(answer))); } catch (Exception e) { logger.debug("Can not process received request", e); } finally { sendAndStateLock.unlock(); } try { listener.doAccAnswerEvent(this, createAccountRequest(request), createAccountAnswer(answer)); } catch (Exception e) { logger.debug("Unable to deliver message to listener.", e); } } else { try { listener.doOtherEvent(this, createAccountRequest(request), createAccountAnswer(answer)); } catch (Exception e) { logger.debug("Can not process received request", e); } } } @Override public void timeoutExpired(Request request) { try { sendAndStateLock.lock(); handleEvent(new Event(Event.Type.FAILED_SEND_RECORD, createAccountRequest(request))); } catch (Exception e) { logger.debug("Can not handle timeout event", e); } finally { sendAndStateLock.unlock(); } } @Override public Answer processRequest(Request request) { Answer a = request.createAnswer(5001); return a; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } protected Request createInterimRecord() { Request interimRecord = session.createRequest(AccountRequest.code, sessionData.getApplicationId(), sessionData.getDestinationRealm(), sessionData.getDestinationHost()); interimRecord.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 3); return interimRecord; } protected Request createSessionTermRequest() { return session.createRequest(Message.SESSION_TERMINATION_REQUEST, sessionData.getApplicationId(), sessionData.getDestinationRealm(), sessionData.getDestinationHost()); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ClientAccSessionImpl other = (ClientAccSessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/acc/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.acc; import org.jdiameter.api.Avp; import org.jdiameter.api.ResultCode; import org.jdiameter.api.acc.events.AccountAnswer; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class Event implements StateEvent { enum Type { SEND_EVENT_RECORD, SEND_START_RECORD, SEND_INTERIM_RECORD, SEND_STOP_RECORD, FAILED_SEND_RECORD, RECEIVED_RECORD, FAILED_RECEIVE_RECORD } Type type; AppEvent data; Event(Type type) { this.type = type; } Event(AccountAnswer accountAnswer) throws Exception { int resCode = ResultCode.SUCCESS; try { resCode = accountAnswer.getMessage().getAvps().getAvp(Avp.RESULT_CODE).getInteger32(); } catch (Exception exc) { } type = (resCode == ResultCode.SUCCESS || (resCode / 1000 == 4)) ? Type.RECEIVED_RECORD : Type.FAILED_RECEIVE_RECORD; data = accountAnswer; } Event(AccountRequest accountRequest) throws Exception { data = accountRequest; int type = accountRequest.getAccountingRecordType(); switch (type) { case 1: this.type = Type.SEND_EVENT_RECORD; break; case 2: this.type = Type.SEND_START_RECORD; break; case 3: this.type = Type.SEND_INTERIM_RECORD; break; case 4: this.type = Type.SEND_STOP_RECORD; break; default: throw new Exception("Unknown type " + type); } } Event(Type type, AccountRequest accountRequest) throws Exception { this.type = type; this.data = accountRequest; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public void setData(Object o) { data = (AppEvent) o; } @Override public Object getData() { return data; } @Override public int compareTo(Object o) { return 0; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/acc/IClientAccSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.acc; import java.io.Serializable; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.acc.ClientAccSessionState; import org.jdiameter.common.api.app.acc.IAccSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientAccSessionData extends IAccSessionData { void setClientAccSessionState(ClientAccSessionState state); ClientAccSessionState getClientAccSessionState(); void setInterimTimerId(Serializable tid); Serializable getInterimTimerId(); void setDestinationHost(String destHost); String getDestinationHost(); void setDestinationRealm(String destRealm); String getDestinationRealm(); void setBuffer(Request event); Request getBuffer(); void setApplicationId(ApplicationId aid); ApplicationId getApplicationId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/auth/ClientAuthSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.auth; import java.io.Serializable; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.auth.ClientAuthSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientAuthSessionDataLocalImpl extends AppSessionDataLocalImpl implements IClientAuthSessionData { protected ClientAuthSessionState state = ClientAuthSessionState.IDLE; protected boolean stateless = true; protected String destinationHost; protected String destinationRealm; protected Serializable tsTimerId; /* * (non-Javadoc) * * @see * org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setClientAuthSessionState(org.jdiameter.common.api.app.auth. * ClientAuthSessionState) */ @Override public void setClientAuthSessionState(ClientAuthSessionState state) { this.state = state; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#getClientAuthSessionState() */ @Override public ClientAuthSessionState getClientAuthSessionState() { return this.state; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#isStateless() */ @Override public boolean isStateless() { return this.stateless; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setStateless(boolean) */ @Override public void setStateless(boolean b) { this.stateless = b; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#getDestinationHost() */ @Override public String getDestinationHost() { return this.destinationHost; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setDestinationHost(java.lang.String) */ @Override public void setDestinationHost(String host) { this.destinationHost = host; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#getDestinationRealm() */ @Override public String getDestinationRealm() { return this.destinationRealm; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setDestinationRealm(java.lang.String) */ @Override public void setDestinationRealm(String realm) { this.destinationRealm = realm; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#getTsTimerId() */ @Override public Serializable getTsTimerId() { return this.tsTimerId; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setTsTimerId(java.io.Serializable) */ @Override public void setTsTimerId(Serializable tid) { this.tsTimerId = tid; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/auth/ClientAuthSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.auth; import org.jdiameter.api.*; import org.jdiameter.api.app.*; import org.jdiameter.api.auth.ClientAuthSession; import org.jdiameter.api.auth.ClientAuthSessionListener; import org.jdiameter.api.auth.events.*; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.auth.ClientAuthSessionState; import org.jdiameter.common.api.app.auth.IAuthMessageFactory; import org.jdiameter.common.api.app.auth.IClientAuthActionContext; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.auth.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import static org.jdiameter.api.Message.SESSION_TERMINATION_REQUEST; import static org.jdiameter.common.api.app.auth.ClientAuthSessionState.*; /** * Client Authorization session implementation * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientAuthSessionImpl extends AppAuthSessionImpl implements ClientAuthSession, EventListener, NetworkReqListener { protected static final Logger logger = LoggerFactory.getLogger(ClientAuthSessionImpl.class); // Session State Handling --------------------------------------------------- //protected boolean stateless = false; //protected ClientAuthSessionState state = IDLE; protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IAuthMessageFactory factory; protected transient IClientAuthActionContext context; protected transient ClientAuthSessionListener listener; //protected String destHost, destRealm; //protected ScheduledFuture sessionTimer; //protected Serializable timerId_ts; protected static final String TIMER_NAME_TS = "AUTH_TS"; protected IClientAuthSessionData sessionData; // Constructors ------------------------------------------------------------- public ClientAuthSessionImpl(IClientAuthSessionData sessionData, ISessionFactory sf, ClientAuthSessionListener lst, IAuthMessageFactory fct, StateChangeListener scListener, IClientAuthActionContext context, boolean stateless) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationId() == null) { throw new IllegalArgumentException("ApplicationId can not be null"); } super.appId = fct.getApplicationId(); this.listener = lst; this.factory = fct; this.context = context; this.sessionData = sessionData; this.sessionData.setStateless(stateless); super.addStateChangeNotification(scListener); } public void setListener(ClientAuthSessionListener listener) { this.listener = listener; } // ClientAuthSession Implementation methods --------------------------------- @Override public void sendAbortSessionAnswer(AbortSessionAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_SESSION_ABORT_ANSWER, answer); } @Override public void sendAuthRequest(AppRequestEvent request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_AUTH_REQUEST, request); } @Override public void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_AUTH_ANSWER, answer); } @Override public void sendSessionTerminationRequest(SessionTermRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_SESSION_TERMINATION_REQUEST, request); } protected void send(Event.Type type, AppEvent event) throws InternalException { //This is called from app thread, it may be due to callback from our delivery thread, but we dont care try { sendAndStateLock.lock(); if (type != null) { handleEvent(new Event(type, event)); } session.send(event.getMessage(), this); // Store last destination information AvpSet avps = event.getMessage().getAvps(); Avp destRealmAvp = avps.getAvp(Avp.DESTINATION_REALM); if (destRealmAvp != null) { sessionData.setDestinationRealm(destRealmAvp.getDiameterIdentity()); } Avp destHostAvp = avps.getAvp(Avp.DESTINATION_HOST); if (destHostAvp != null) { sessionData.setDestinationHost(destHostAvp.getDiameterIdentity()); } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } @Override public boolean isStateless() { return this.sessionData.isStateless(); } @SuppressWarnings("unchecked") protected void setState(ClientAuthSessionState newState) { IAppSessionState oldState = sessionData.getClientAuthSessionState(); sessionData.setClientAuthSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } } @Override @SuppressWarnings("unchecked") public E getState(Class eClass) { return eClass == ClientAuthSessionState.class ? (E) sessionData.getClientAuthSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return sessionData.isStateless() ? handleEventForStatelessSession(event) : handleEventForStatefulSession(event); } public boolean handleEventForStatelessSession(StateEvent event) throws InternalException, OverloadException { try { ClientAuthSessionState state = sessionData.getClientAuthSessionState(); ClientAuthSessionState oldState = state; switch (state) { case IDLE: switch ((Event.Type) event.getType()) { case SEND_AUTH_REQUEST: // Current State: IDLE // Event: Client or Device Requests access // Action: Send service specific auth req // New State: PENDING setState(PENDING); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; case PENDING: switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_ANSWER: try { // Current State: PENDING // Event: Successful service-specific authorization answer received with Auth-Session-State set to NO_STATE_MAINTAINED // Action: Grant Access // New State: OPEN setState(OPEN); listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData()); } catch (Exception e) { // Current State: PENDING // Event: Failed service-specific authorization answer received // Action: Cleanup // New State: IDLE setState(IDLE); } break; default: logger.debug("Unknown event {}", event.getType()); break; } break; case OPEN: switch ((Event.Type) event.getType()) { case SEND_SESSION_ABORT_ANSWER: case SEND_SESSION_TERMINATION_REQUEST: // Current State: OPEN // Event: Service to user is terminated // Action: Disconnect User/Device // New State: IDLE setState(IDLE); break; case TIMEOUT_EXPIRES: // Current State: OPEN // Event: Session-Timeout Expires on Access Device // Action: Send STR // New State: DISCON try { if (context != null) { context.accessTimeoutElapses(this); Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { // IDLE is the same as DISCON setState(IDLE); } break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } // post processing if (oldState != state) { if (DISCONNECTED.equals(state) || IDLE.equals(state)) { cancelTsTimer(); } else if (OPEN.equals(state) && context != null && context.getAccessTimeout() > 0) { // sessionTimer = scheduler.schedule(new Runnable() { // public void run() { // if (context != null) { // try { // handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, null)); // } // catch (Exception e) { // logger.debug("Can not handle event", e); // } // } // } // }, context.createAccessTimer(), TimeUnit.MILLISECONDS); cancelTsTimer(); startTsTimer(); } } } catch (Throwable t) { throw new InternalException(t); } return true; } public boolean handleEventForStatefulSession(StateEvent event) throws InternalException, OverloadException { ClientAuthSessionState state = sessionData.getClientAuthSessionState(); ClientAuthSessionState oldState = state; try { switch (state) { case IDLE: { switch ((Event.Type) event.getType()) { case SEND_AUTH_REQUEST: // Current State: IDLE // Event: Client or Device Requests access // Action: Send service specific auth req // New State: PENDING setState(PENDING); break; case RECEIVE_ABORT_SESSION_REQUEST: // Current State: IDLE // Event: ASR Received for unknown session // Action: Send ASA with Result-Code = UNKNOWN_SESSION_ID // New State: IDLE // FIXME: Should send ASA with UNKNOWN_SESSION_ID instead ? listener.doAbortSessionRequestEvent(this, (AbortSessionRequest) event.getData()); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } case PENDING: { switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_ANSWER: try { // Current State: PENDING // Event: Successful service-specific authorization answer received with default Auth-Session-State value // Action: Grant Access // New State: OPEN setState(OPEN); listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData()); } catch (InternalException e) { // Current State: PENDING // Event: Successful service-specific authorization answer received but service not provided // Action: Send STR // New State: DISCON // Current State: PENDING // Event: Error Processing successful service-specific authorization answer // Action: Send STR // New State: DISCON setState(DISCONNECTED); } catch (Exception e) { // Current State: PENDING // Event: Failed service-specific authorization answer received // Action: Cleanup // New State: IDLE setState(IDLE); } break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } case OPEN: { switch ((Event.Type) event.getType()) { case SEND_AUTH_REQUEST: // Current State: OPEN // Event: User or client device requests access to service // Action: Send service specific auth req // New State: OPEN break; case RECEIVE_AUTH_ANSWER: try { // Current State: OPEN // Event: Successful service-specific authorization answer received // Action: Provide Service // New State: OPEN listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData()); } catch (Exception e) { // Current State: OPEN // Event: ASR Received, client will comply with request to end the session // Action: Send ASA with Result-Code = SUCCESS, Send STR // New State: DISCON setState(DISCONNECTED); } break; case RECEIVE_FAILED_AUTH_ANSWER: // Current State: OPEN // Event: Failed Service-specific authorization answer received // Action: Disconnect User/Device // New State: IDLE try { if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(IDLE); listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData()); } break; case RECEIVE_ABORT_SESSION_REQUEST: // Current State: OPEN // Event: ASR Received (client to take comply or not) // Action: TBD // New State: TBD (comply = DISCON, !comply = OPEN) listener.doAbortSessionRequestEvent(this, (AbortSessionRequestImpl) event.getData()); break; case SEND_SESSION_TERMINATION_REQUEST: setState(DISCONNECTED); break; case TIMEOUT_EXPIRES: // Current State: OPEN // Event: Session-Timeout Expires on Access Device // Action: Send STR // New State: DISCON // Current State: OPEN // Event: Authorization-Lifetime + Auth-Grace-Period expires on access device // Action: Send STR // New State: DISCON try { if (context != null) { context.accessTimeoutElapses(this); Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(DISCONNECTED); } break; } break; } case DISCONNECTED: { switch ((Event.Type) event.getType()) { case RECEIVE_ABORT_SESSION_REQUEST: // Current State: DISCON // Event: ASR Received // Action: Send ASA // New State: DISCON listener.doAbortSessionRequestEvent(this, (AbortSessionRequest) event.getData()); break; case RECEIVE_SESSION_TERINATION_ANSWER: // Current State: DISCON // Event: STA Received // Action: Disconnect User/Device // New State: IDLE listener.doSessionTerminationAnswerEvent(this, ((SessionTermAnswerImpl) event.getData())); setState(IDLE); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } default: { logger.debug("Unknown state {}", state); break; } } // post processing if (oldState != state) { if (OPEN.equals(state) && context != null && context.getAccessTimeout() > 0) { // scheduler.schedule(new Runnable() { // public void run() { // if (context != null) { // try { // handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, null)); // } // catch (Exception e) { // logger.debug("Can not handle event", e); // } // } // } // }, context.createAccessTimer(), TimeUnit.MILLISECONDS); cancelTsTimer(); startTsTimer(); } } } catch (Throwable t) { throw new InternalException(t); } return true; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery ad = new AnswerDelivery(); ad.session = this; ad.request = request; ad.answer = answer; super.scheduler.execute(ad); } @Override public void timeoutExpired(Request request) { try { sendAndStateLock.lock(); //FIXME: should this also be async ? handleEvent(new Event(Event.Type.RECEIVE_FAILED_AUTH_ANSWER, new AppRequestEventImpl(request))); } catch (Exception e) { logger.debug("Can not handle timeout event", e); } finally { sendAndStateLock.unlock(); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } protected void startTsTimer() throws IllegalArgumentException, InternalException { try { sendAndStateLock.lock(); sessionData.setTsTimerId( super.timerFacility.schedule(sessionData.getSessionId(), TIMER_NAME_TS, context.getAccessTimeout())); } finally { sendAndStateLock.unlock(); } } protected void cancelTsTimer() { try { sendAndStateLock.lock(); Serializable timerId = sessionData.getTsTimerId(); if (timerId != null) { super.timerFacility.cancel(timerId); sessionData.setTsTimerId(null); } } finally { sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TIMER_NAME_TS)) { try { sendAndStateLock.lock(); sessionData.setTsTimerId(null); if (context != null) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, null)); } catch (Exception e) { logger.debug("Can not handle event", e); } } } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } protected AbortSessionAnswer createAbortSessionAnswer(Answer answer) { return new AbortSessionAnswerImpl(answer); } protected AbortSessionRequest createAbortSessionRequest(Request request) { return new AbortSessionRequestImpl(request); } protected ReAuthAnswer createReAuthAnswer(Answer answer) { return new ReAuthAnswerImpl(answer); } protected ReAuthRequest createReAuthRequest(Request request) { return new ReAuthRequestImpl(request); } protected SessionTermAnswer createSessionTermAnswer(Answer answer) { return new SessionTermAnswerImpl(answer); } protected SessionTermRequest createSessionTermRequest(Request request) { return new SessionTermRequestImpl(request); } protected Request createSessionTermRequest() { return session.createRequest(SESSION_TERMINATION_REQUEST, appId, sessionData.getDestinationRealm(), sessionData.getDestinationHost()); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } ClientAuthSessionImpl other = (ClientAuthSessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ClientAuthSession session; Request request; @Override public void run() { try { if (request.getCommandCode() == AbortSessionRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_ABORT_SESSION_REQUEST, createAbortSessionRequest(request))); } else if (request.getCommandCode() == ReAuthRequest.code) { listener.doReAuthRequestEvent(session, createReAuthRequest(request)); } else { listener.doOtherEvent(session, factory.createAuthRequest(request), null); } } catch (Exception e) { logger.debug("Can not process received request", e); } } } private class AnswerDelivery implements Runnable { ClientAuthSession session; Answer answer; Request request; @Override public void run() { try { sendAndStateLock.lock(); // FIXME: baranowb: this shouldn't be like that? if (answer.getCommandCode() == factory.getAuthMessageCommandCode()) { handleEvent(new Event(Event.Type.RECEIVE_AUTH_ANSWER, factory.createAuthAnswer(answer))); } else if (answer.getCommandCode() == SessionTermAnswer.code) { handleEvent(new Event(Event.Type.RECEIVE_SESSION_TERINATION_ANSWER, createSessionTermAnswer(answer))); } else { listener.doOtherEvent(session, factory.createAuthRequest(request), new AppAnswerEventImpl(answer)); } } catch (Exception e) { logger.debug("Can not process received message", e); } finally { sendAndStateLock.unlock(); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/auth/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.auth; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class Event implements StateEvent { enum Type { SEND_AUTH_REQUEST, SEND_AUTH_ANSWER, SEND_SESSION_TERMINATION_REQUEST, SEND_SESSION_ABORT_ANSWER, RECEIVE_AUTH_ANSWER, RECEIVE_FAILED_AUTH_ANSWER, RECEIVE_ABORT_SESSION_REQUEST, RECEIVE_SESSION_TERINATION_ANSWER, TIMEOUT_EXPIRES } Type type; AppEvent data; Event(Type type, AppEvent data) { this.type = type; this.data = data; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public void setData(Object o) { data = (AppEvent) o; } @Override public Object getData() { return data; } @Override public int compareTo(Object o) { return 0; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/auth/IClientAuthSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.auth; import java.io.Serializable; import org.jdiameter.common.api.app.auth.ClientAuthSessionState; import org.jdiameter.common.api.app.auth.IAuthSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientAuthSessionData extends IAuthSessionData { void setClientAuthSessionState(ClientAuthSessionState state); ClientAuthSessionState getClientAuthSessionState(); boolean isStateless(); void setStateless(boolean b); String getDestinationHost(); void setDestinationHost(String host); String getDestinationRealm(); void setDestinationRealm(String realm); Serializable getTsTimerId(); void setTsTimerId(Serializable realm); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cca/ClientCCASessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.cca; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.cca.ClientCCASessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientCCASessionDataLocalImpl extends AppSessionDataLocalImpl implements IClientCCASessionData { protected boolean isEventBased = true; protected boolean requestTypeSet = false; protected ClientCCASessionState state = ClientCCASessionState.IDLE; protected Serializable txTimerId; //protected JCreditControlRequest txTimerRequest; protected Request txTimerRequest; // Event Based Buffer //protected Message buffer = null; protected Request buffer; protected int gatheredRequestedAction = NON_INITIALIZED; protected int gatheredCCFH = NON_INITIALIZED; protected int gatheredDDFH = NON_INITIALIZED; /** * */ public ClientCCASessionDataLocalImpl() { } @Override public boolean isEventBased() { return isEventBased; } @Override public void setEventBased(boolean isEventBased) { this.isEventBased = isEventBased; } @Override public boolean isRequestTypeSet() { return requestTypeSet; } @Override public void setRequestTypeSet(boolean requestTypeSet) { this.requestTypeSet = requestTypeSet; } @Override public ClientCCASessionState getClientCCASessionState() { return state; } @Override public void setClientCCASessionState(ClientCCASessionState state) { this.state = state; } @Override public Serializable getTxTimerId() { return txTimerId; } @Override public void setTxTimerId(Serializable txTimerId) { this.txTimerId = txTimerId; } @Override public Request getTxTimerRequest() { return txTimerRequest; } @Override public void setTxTimerRequest(Request txTimerRequest) { this.txTimerRequest = txTimerRequest; } @Override public Request getBuffer() { return buffer; } @Override public void setBuffer(Request buffer) { this.buffer = buffer; } @Override public int getGatheredRequestedAction() { return gatheredRequestedAction; } @Override public void setGatheredRequestedAction(int gatheredRequestedAction) { this.gatheredRequestedAction = gatheredRequestedAction; } @Override public int getGatheredCCFH() { return gatheredCCFH; } @Override public void setGatheredCCFH(int gatheredCCFH) { this.gatheredCCFH = gatheredCCFH; } @Override public int getGatheredDDFH() { return gatheredDDFH; } @Override public void setGatheredDDFH(int gatheredDDFH) { this.gatheredDDFH = gatheredDDFH; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cca/ClientCCASessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.cca; import org.jdiameter.api.*; import org.jdiameter.api.app.*; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.cca.ClientCCASession; import org.jdiameter.api.cca.ClientCCASessionListener; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.cca.Event.Type; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.cca.ClientCCASessionState; import org.jdiameter.common.api.app.cca.ICCAMessageFactory; import org.jdiameter.common.api.app.cca.IClientCCASessionContext; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.cca.AppCCASessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Client Credit-Control Application session implementation * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ClientCCASessionImpl extends AppCCASessionImpl implements ClientCCASession, NetworkReqListener, EventListener { private static final Logger logger = LoggerFactory.getLogger(ClientCCASessionImpl.class); // session data pojo, local reference so we dont have to cast super.data to IClientCCASessionData protected IClientCCASessionData sessionData; // Session State Handling --------------------------------------------------- protected Lock sendAndStateLock = new ReentrantLock(); // Session Based Queue protected ArrayList eventQueue = new ArrayList(); //FIXME: this is not replicable? // Factories and Listeners -------------------------------------------------- protected ICCAMessageFactory factory; protected ClientCCASessionListener listener; protected IClientCCASessionContext context; protected static final String TX_TIMER_NAME = "CCA_CLIENT_TX_TIMER"; protected static final long TX_TIMER_DEFAULT_VALUE = 30 * 60 * 1000; // miliseconds protected long[] authAppIds = new long[]{4}; protected static final int CCFH_TERMINATE = 0; protected static final int CCFH_CONTINUE = 1; protected static final int CCFH_RETRY_AND_TERMINATE = 2; private static final int DDFH_TERMINATE_OR_BUFFER = 0; private static final int DDFH_CONTINUE = 1; // CC-Request-Type Values --------------------------------------------------- private static final int DIRECT_DEBITING = 0; private static final int REFUND_ACCOUNT = 1; private static final int CHECK_BALANCE = 2; private static final int PRICE_ENQUIRY = 3; private static final int EVENT_REQUEST = 4; // Error Codes -------------------------------------------------------------- private static final long END_USER_SERVICE_DENIED = 4010; private static final long CREDIT_CONTROL_NOT_APPLICABLE = 4011; private static final long USER_UNKNOWN = 5030; private static final long DIAMETER_UNABLE_TO_DELIVER = 3002L; private static final long DIAMETER_TOO_BUSY = 3004L; private static final long DIAMETER_LOOP_DETECTED = 3005L; protected static final Set temporaryErrorCodes; static { HashSet tmp = new HashSet(); tmp.add(DIAMETER_UNABLE_TO_DELIVER); tmp.add(DIAMETER_TOO_BUSY); tmp.add(DIAMETER_LOOP_DETECTED); temporaryErrorCodes = Collections.unmodifiableSet(tmp); } public ClientCCASessionImpl(IClientCCASessionData data, ICCAMessageFactory fct, ISessionFactory sf, ClientCCASessionListener lst, IClientCCASessionContext ctx, StateChangeListener stLst) { super(sf, data); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (data == null) { throw new IllegalArgumentException("SessionData can not be null"); } if (fct.getApplicationIds() == null) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.sessionData = data; this.context = ctx; this.authAppIds = fct.getApplicationIds(); this.listener = lst; this.factory = fct; super.addStateChangeNotification(stLst); } public void setListener(ClientCCASessionListener listener) { this.listener = listener; } protected int getLocalCCFH() { return sessionData.getGatheredCCFH() >= 0 ? sessionData.getGatheredCCFH() : context.getDefaultCCFHValue(); } protected int getLocalDDFH() { return sessionData.getGatheredDDFH() >= 0 ? sessionData.getGatheredDDFH() : context.getDefaultDDFHValue(); } @Override public void sendCreditControlRequest(JCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { extractFHAVPs(request, null); this.handleEvent(new Event(true, request, null)); } @Override public void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { this.handleEvent(new Event(Event.Type.SEND_RAA, null, answer)); } @Override public boolean isStateless() { return false; } public boolean isEventBased() { return this.sessionData.isEventBased(); } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == ClientCCASessionState.class ? (E) this.sessionData.getClientCCASessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return this.isEventBased() ? handleEventForEventBased(event) : handleEventForSessionBased(event); } protected boolean handleEventForEventBased(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); final Event localEvent = (Event) event; final Event.Type eventType = (Type) localEvent.getType(); final ClientCCASessionState state = this.sessionData.getClientCCASessionState(); switch (state) { case IDLE: switch (eventType) { case SEND_EVENT_REQUEST: // Current State: IDLE // Event: Client or device requests a one-time service // Action: Send CC event request, start Tx // New State: PENDING_E startTx((JCreditControlRequest) localEvent.getRequest()); setState(ClientCCASessionState.PENDING_EVENT); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table logger.debug("Failure handling send event request", e); handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_EVENT: switch (eventType) { case RECEIVE_EVENT_ANSWER: AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer(); try { long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode) || isTransient(resultCode)) { // Current State: PENDING_E // Event: Successful CC event answer received // Action: Grant service to end user // New State: IDLE setState(ClientCCASessionState.IDLE, false); } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((JCreditControlAnswer) answer, (JCreditControlRequest) localEvent.getRequest(), eventType); } deliverCCAnswer((JCreditControlRequest) localEvent.getRequest(), (JCreditControlAnswer) localEvent.getAnswer()); } catch (AvpDataException e) { logger.debug("Failure handling received answer event", e); setState(ClientCCASessionState.IDLE, false); } break; case Tx_TIMER_FIRED: handleTxExpires(localEvent.getRequest().getMessage()); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_BUFFERED: switch (eventType) { case RECEIVE_EVENT_ANSWER: // Current State: PENDING_B // Event: Successful CC answer received // Action: Delete request // New State: IDLE setState(ClientCCASessionState.IDLE, false); sessionData.setBuffer(null); deliverCCAnswer((JCreditControlRequest) localEvent.getRequest(), (JCreditControlAnswer) localEvent.getAnswer()); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } dispatch(); return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } protected boolean handleEventForSessionBased(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); Event localEvent = (Event) event; Event.Type eventType = (Type) localEvent.getType(); ClientCCASessionState state = this.sessionData.getClientCCASessionState(); switch (state) { case IDLE: switch (eventType) { case SEND_INITIAL_REQUEST: // Current State: IDLE // Event: Client or device requests access/service // Action: Send CC initial request, start Tx // New State: PENDING_I startTx((JCreditControlRequest) localEvent.getRequest()); setState(ClientCCASessionState.PENDING_INITIAL); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_INITIAL: AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVED_INITIAL_ANSWER: long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_I // Event: Successful CC initial answer received // Action: Stop Tx // New State: OPEN stopTx(); setState(ClientCCASessionState.OPEN); } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((JCreditControlAnswer) answer, (JCreditControlRequest) localEvent.getRequest(), eventType); } deliverCCAnswer((JCreditControlRequest) localEvent.getRequest(), (JCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: handleTxExpires(localEvent.getRequest().getMessage()); break; case SEND_UPDATE_REQUEST: case SEND_TERMINATE_REQUEST: // Current State: PENDING_I // Event: User service terminated // Action: Queue termination event // New State: PENDING_I // Current State: PENDING_I // Event: Change in rating condition // Action: Queue changed rating condition event // New State: PENDING_I eventQueue.add(localEvent); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case OPEN: switch (eventType) { case SEND_UPDATE_REQUEST: // Current State: OPEN // Event: Granted unit elapses and no final unit indication received // Action: Send CC update request, start Tx // New State: PENDING_U // Current State: OPEN // Event: Change in rating condition in queue // Action: Send CC update request, start Tx // New State: PENDING_U // Current State: OPEN // Event: Change in rating condition or Validity-Time elapses // Action: Send CC update request, start Tx // New State: PENDING_U // Current State: OPEN // Event: RAR received // Action: Send RAA followed by CC update request, start Tx // New State: PENDING_U startTx((JCreditControlRequest) localEvent.getRequest()); setState(ClientCCASessionState.PENDING_UPDATE); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case SEND_TERMINATE_REQUEST: // Current State: OPEN // Event: Granted unit elapses and final unit action equal to TERMINATE received // Action: Terminate end user�s service, send CC termination request // New State: PENDING_T // Current State: OPEN // Event: Service terminated in queue // Action: Send CC termination request // New State: PENDING_T // Current State: OPEN // Event: User service terminated // Action: Send CC termination request // New State: PENDING_T setState(ClientCCASessionState.PENDING_TERMINATION); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case RECEIVED_RAR: deliverRAR((ReAuthRequest) localEvent.getRequest()); break; case SEND_RAA: try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_UPDATE: answer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVED_UPDATE_ANSWER: long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_U // Event: Successful CC update answer received // Action: Stop Tx // New State: OPEN stopTx(); setState(ClientCCASessionState.OPEN); } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((JCreditControlAnswer) answer, (JCreditControlRequest) localEvent.getRequest(), eventType); } deliverCCAnswer((JCreditControlRequest) localEvent.getRequest(), (JCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: handleTxExpires(localEvent.getRequest().getMessage()); break; case SEND_UPDATE_REQUEST: case SEND_TERMINATE_REQUEST: // Current State: PENDING_U // Event: User service terminated // Action: Queue termination event // New State: PENDING_U // Current State: PENDING_U // Event: Change in rating condition // Action: Queue changed rating condition event // New State: PENDING_U eventQueue.add(localEvent); break; case RECEIVED_RAR: deliverRAR((ReAuthRequest) localEvent.getRequest()); break; case SEND_RAA: // Current State: PENDING_U // Event: RAR received // Action: Send RAA // New State: PENDING_U try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; } break; case PENDING_TERMINATION: switch (eventType) { case SEND_UPDATE_REQUEST: try { // Current State: PENDING_T // Event: Change in rating condition // Action: - // New State: PENDING_T dispatchEvent(localEvent.getRequest()); // No transition } catch (Exception e) { // This handles failure to send in PendingI state in FSM table // handleSendFailure(e, eventType); } break; case RECEIVED_TERMINATED_ANSWER: // Current State: PENDING_T // Event: Successful CC termination answer received // Action: - // New State: IDLE // Current State: PENDING_T // Event: Failure to send, temporary error, or failed answer // Action: - // New State: IDLE //FIXME: Alex broke this, setting back "true" ? //setState(ClientCCASessionState.IDLE, false); deliverCCAnswer((JCreditControlRequest) localEvent.getRequest(), (JCreditControlAnswer) localEvent.getAnswer()); setState(ClientCCASessionState.IDLE, true); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; default: // any other state is bad setState(ClientCCASessionState.IDLE, true); } dispatch(); return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery ad = new AnswerDelivery(); ad.session = this; ad.request = request; ad.answer = answer; super.scheduler.execute(ad); } @Override public void timeoutExpired(Request request) { if (request.getCommandCode() == JCreditControlAnswer.code) { try { handleSendFailure(null, null, request); } catch (Exception e) { logger.debug("Failure processing timeout message for request", e); } } } protected void startTx(JCreditControlRequest request) { long txTimerValue = context.getDefaultTxTimerValue(); if (txTimerValue < 0) { txTimerValue = TX_TIMER_DEFAULT_VALUE; } stopTx(); logger.debug("Scheduling TX Timer {}", txTimerValue); //this.txFuture = scheduler.schedule(new TxTimerTask(this, request), txTimerValue, TimeUnit.SECONDS); try { this.sessionData.setTxTimerRequest((Request) ((AppEventImpl) request).getMessage()); } catch (Exception e) { throw new IllegalArgumentException("Failed to store request.", e); } this.sessionData.setTxTimerId(this.timerFacility.schedule(this.getSessionId(), TX_TIMER_NAME, TX_TIMER_DEFAULT_VALUE)); } protected void stopTx() { Serializable txTimerId = this.sessionData.getTxTimerId(); if (txTimerId != null) { this.sessionData.setTxTimerRequest(null); this.timerFacility.cancel(txTimerId); this.sessionData.setTxTimerId(null); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TX_TIMER_NAME)) { new TxTimerTask(this, this.sessionData.getTxTimerRequest()).run(); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } protected void setState(ClientCCASessionState newState) { setState(newState, true); } @SuppressWarnings("unchecked") protected void setState(ClientCCASessionState newState, boolean release) { try { IAppSessionState oldState = this.sessionData.getClientCCASessionState(); this.sessionData.setClientCCASessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == ClientCCASessionState.IDLE) { if (release) { this.release(); } stopTx(); } } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure switching to state " + this.sessionData.getClientCCASessionState() + " (release=" + release + ")", e); } } } @Override public void release() { if (isValid()) { try { this.sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void handleSendFailure(Exception e, Event.Type eventType, Message request) throws Exception { logger.debug("Failed to send message, type: {} message: {}, failure: {}", new Object[]{eventType, request, e != null ? e.getLocalizedMessage() : ""}); try { this.sendAndStateLock.lock(); ClientCCASessionState state = this.sessionData.getClientCCASessionState(); // Event Based ---------------------------------------------------------- if (isEventBased()) { int gatheredRequestedAction = this.sessionData.getGatheredRequestedAction(); switch (state) { case PENDING_EVENT: if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE setState(ClientCCASessionState.IDLE); context.indicateServiceError(this); } else if (gatheredRequestedAction == DIRECT_DEBITING) { switch (getLocalDDFH()) { case DDFH_TERMINATE_OR_BUFFER: // Current State: PENDING_E // Event: Failure to send; request action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER // Action: Store request with T-flag // New State: IDLE request.setReTransmitted(true); this.sessionData.setBuffer((Request) request); setState(ClientCCASessionState.IDLE, false); break; case DDFH_CONTINUE: // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnDeliverFailure(this, request); break; default: logger.warn("Invalid Direct-Debiting-Failure-Handling AVP value {}", getLocalDDFH()); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag // New State: IDLE setState(ClientCCASessionState.IDLE, false); request.setReTransmitted(true); this.sessionData.setBuffer((Request) request); } else { logger.warn("Invalid Requested-Action AVP value {}", gatheredRequestedAction); } break; case PENDING_BUFFERED: // Current State: PENDING_B // Event: Failure to send or temporary error // Action: - // New State: IDLE setState(ClientCCASessionState.IDLE, false); this.sessionData.setBuffer(null); // FIXME: Action does not mention, but ... break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } } // Session Based -------------------------------------------------------- else { switch (getLocalCCFH()) { case CCFH_CONTINUE: // Current State: PENDING_I // Event: Failure to send, or temporary error and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE // Current State: PENDING_U // Event: Failure to send, or temporary error and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE setState(ClientCCASessionState.IDLE, false); this.context.grantAccessOnDeliverFailure(this, request); break; default: // Current State: PENDING_I // Event: Failure to send, or temporary error and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE // Action: Terminate end user�s service // New State: IDLE // Current State: PENDING_U // Event: Failure to send, or temporary error and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE // Action: Terminate end user�s service // New State: IDLE this.context.denyAccessOnDeliverFailure(this, request); setState(ClientCCASessionState.IDLE, true); break; } } dispatch(); } finally { this.sendAndStateLock.unlock(); } } protected void handleFailureMessage(JCreditControlAnswer answer, JCreditControlRequest request, Event.Type eventType) { try { // Event Based ---------------------------------------------------------- long resultCode = answer.getResultCodeAvp().getUnsigned32(); ClientCCASessionState state = this.sessionData.getClientCCASessionState(); Serializable txTimerId = this.sessionData.getTxTimerId(); if (isEventBased()) { int gatheredRequestedAction = this.sessionData.getGatheredRequestedAction(); switch (state) { case PENDING_EVENT: if (resultCode == END_USER_SERVICE_DENIED || resultCode == USER_UNKNOWN) { if (txTimerId != null) { // Current State: PENDING_E // Event: CC event answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN and Tx running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) { // Current State: PENDING_E // Event: Failed answer or answer received w/ result code END_USER_SERVICE DENIED or USER_UNKNOWN; requested action DIRECT_DEBITING; Tx expired // Action: - // New State: IDLE setState(ClientCCASessionState.IDLE); } } else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) { // Current State: PENDING_E // Event: CC event answer received with result code CREDIT_CONTROL_NOT_APPLICABLE; requested action DIRECT_DEBITING // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } else if (temporaryErrorCodes.contains(resultCode)) { if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE context.indicateServiceError(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Temporary error, and requested action REFUND_ACCOUNT // Action: Store request // New State: IDLE this.sessionData.setBuffer((Request) request.getMessage()); setState(ClientCCASessionState.IDLE, false); } else { logger.warn( "Invalid combination for CCA Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } } else { // Failure if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE context.indicateServiceError(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failed CC event answer received; requested action REFUND_ACCOUNT // Action: Indicate service error and delete request // New State: IDLE this.sessionData.setBuffer(null); context.indicateServiceError(this); deliverCCAnswer(request, answer); setState(ClientCCASessionState.IDLE); } else { logger.warn( "Invalid combination for CCA Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } } break; case PENDING_BUFFERED: // Current State: PENDING_B // Event: Failed CC answer received // Action: Delete request // New State: IDLE this.sessionData.setBuffer(null); setState(ClientCCASessionState.IDLE, false); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); } } // Session Based -------------------------------------------------------- else { switch (state) { case PENDING_INITIAL: if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE) { // Current State: PENDING_I // Event: CC initial answer received with result code equal to CREDIT_CONTROL_NOT_APPLICABLE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); } else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) { // Current State: PENDING_I // Event: CC initial answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: // Current State: PENDING_I // Event: Failed CC initial answer received and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); break; case CCFH_TERMINATE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_I // Event: Failed CC initial answer received and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); break; default: logger.warn("Invalid value for CCFH: {}", getLocalCCFH()); break; } } break; case PENDING_UPDATE: if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE) { // Current State: PENDING_U // Event: CC update answer received with result code equal to CREDIT_CONTROL_NOT_APPLICABLE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); } else if (resultCode == END_USER_SERVICE_DENIED) { // Current State: PENDING_U // Event: CC update answer received with result code END_USER_SERVICE_DENIED // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: // Current State: PENDING_U // Event: Failed CC update answer received and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); break; case CCFH_TERMINATE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_U // Event: Failed CC update answer received and CCFH equal to CONTINUE or to RETRY_AND_CONTINUE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientCCASessionState.IDLE, false); break; default: logger.warn("Invalid value for CCFH: " + getLocalCCFH()); break; } } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); } } } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug( "Failure handling failure message for Event " + answer + " (" + eventType + ") and Request " + request, e); } } } protected void handleTxExpires(Message message) { // Event Based ---------------------------------------------------------- ClientCCASessionState state = this.sessionData.getClientCCASessionState(); Serializable txTimerId = this.sessionData.getTxTimerId(); if (isEventBased()) { int gatheredRequestedAction = this.sessionData.getGatheredRequestedAction(); if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE context.indicateServiceError(this); setState(ClientCCASessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING) { int gatheredDDFH = this.sessionData.getGatheredDDFH(); if (gatheredDDFH == DDFH_TERMINATE_OR_BUFFER) { // Current State: PENDING_E // Event: Temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER; Tx expired // Action: Store request // New State: IDLE this.sessionData.setBuffer((Request) message); setState(ClientCCASessionState.IDLE, false); } else { // Current State: PENDING_E // Event: Tx expired; requested action DIRECT_DEBITING // Action: Grant service to end user // New State: PENDING_E context.grantAccessOnTxExpire(this); setState(ClientCCASessionState.PENDING_EVENT); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag // New State: IDLE message.setReTransmitted(true); this.sessionData.setBuffer((Request) message); setState(ClientCCASessionState.IDLE, false); } } // Session Based -------------------------------------------------------- else { switch (state) { case PENDING_INITIAL: switch (getLocalCCFH()) { case CCFH_CONTINUE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_I // Event: Tx expired and CCFH equal to CONTINUE or to RETRY_AND_TERMINATE // Action: Grant service to end user // New State: PENDING_I context.grantAccessOnTxExpire(this); break; case CCFH_TERMINATE: // Current State: PENDING_I // Event: Tx expired and CCFH equal to TERMINATE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnTxExpire(this); setState(ClientCCASessionState.IDLE, true); break; default: logger.warn("Invalid value for CCFH: " + getLocalCCFH()); break; } break; case PENDING_UPDATE: switch (getLocalCCFH()) { case CCFH_CONTINUE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_U // Event: Tx expired and CCFH equal to CONTINUE or to RETRY_AND_TERMINATE // Action: Grant service to end user // New State: PENDING_U context.grantAccessOnTxExpire(this); break; case CCFH_TERMINATE: // Current State: PENDING_U // Event: Tx expired and CCFH equal to TERMINATE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnTxExpire(this); setState(ClientCCASessionState.IDLE, true); break; default: logger.error("Bad value of CCFH: " + getLocalCCFH()); break; } break; default: logger.error("Unknown state (" + state + ") on txExpire"); break; } } } /** * This makes checks on queue, moves it to proper state if event there is present on Open state ;] */ protected void dispatch() { // Event Based ---------------------------------------------------------- if (isEventBased()) { // Current State: IDLE // Event: Request in storage // Action: Send stored request // New State: PENDING_B Request buffer = this.sessionData.getBuffer(); if (buffer != null) { setState(ClientCCASessionState.PENDING_BUFFERED); try { dispatchEvent(new AppRequestEventImpl(buffer)); } catch (Exception e) { try { handleSendFailure(e, Event.Type.SEND_EVENT_REQUEST, buffer); } catch (Exception e1) { logger.error("Failure handling buffer send failure", e1); } } } } // Session Based -------------------------------------------------------- else { if (this.sessionData.getClientCCASessionState() == ClientCCASessionState.OPEN && eventQueue.size() > 0) { try { this.handleEvent(eventQueue.remove(0)); } catch (Exception e) { logger.error("Failure handling queued event", e); } } } } protected void deliverCCAnswer(JCreditControlRequest request, JCreditControlAnswer answer) { try { listener.doCreditControlAnswer(this, request, answer); } catch (Exception e) { logger.warn("Failure delivering CCA Answer", e); } } protected void extractFHAVPs(JCreditControlRequest request, JCreditControlAnswer answer) { if (answer != null) { try { if (answer.isCreditControlFailureHandlingAVPPresent()) { this.sessionData.setGatheredCCFH(answer.getCredidControlFailureHandlingAVPValue()); } } catch (Exception e) { logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e); } try { if (answer.isDirectDebitingFailureHandlingAVPPresent()) { this.sessionData.setGatheredDDFH(answer.getDirectDebitingFailureHandlingAVPValue()); } } catch (Exception e) { logger.debug("Failure trying to obtain Direct-Debit-Failure-Handling AVP value", e); } if (!this.sessionData.isRequestTypeSet()) { this.sessionData.setRequestTypeSet(true); // No need to check if it exists.. it must, if not fail with exception this.sessionData.setEventBased(answer.getRequestTypeAVPValue() == EVENT_REQUEST); } } else if (request != null) { try { if (request.isRequestedActionAVPPresent()) { this.sessionData.setGatheredRequestedAction(request.getRequestedActionAVPValue()); } } catch (Exception e) { logger.debug("Failure trying to obtain Request-Action AVP value", e); } if (!this.sessionData.isRequestTypeSet()) { this.sessionData.setRequestTypeSet(true); // No need to check if it exists.. it must, if not fail with exception this.sessionData.setEventBased(request.getRequestTypeAVPValue() == EVENT_REQUEST); } } } protected void deliverRAR(ReAuthRequest request) { try { listener.doReAuthRequest(this, request); } catch (Exception e) { logger.debug("Failure delivering RAR", e); } } protected void dispatchEvent(AppEvent event) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { session.send(event.getMessage(), this); } protected boolean isProvisional(long resultCode) { return resultCode >= 1000 && resultCode < 2000; } protected boolean isSuccess(long resultCode) { return resultCode >= 2000 && resultCode < 3000; } protected boolean isTransient(long resultCode) { return resultCode >= 4000 && resultCode < 5000; } protected boolean isFailure(long code) { return (!isProvisional(code) && !isSuccess(code) && ((code >= 3000 && code < 6000)) && !temporaryErrorCodes.contains(code)); } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } private class TxTimerTask implements Runnable { private ClientCCASession session = null; private Request request = null; private TxTimerTask(ClientCCASession session, Request request) { super(); this.session = session; this.request = request; } @Override public void run() { try { sendAndStateLock.lock(); logger.debug("Fired TX Timer"); sessionData.setTxTimerId(null); try { context.txTimerExpired(session); } catch (Exception e) { logger.debug("Failure handling TX Timer Expired", e); } JCreditControlRequest req = factory.createCreditControlRequest(request); handleEvent(new Event(Event.Type.Tx_TIMER_FIRED, req, null)); } catch (InternalException e) { logger.error("Internal Exception", e); } catch (OverloadException e) { logger.error("Overload Exception", e); } catch (Exception e) { logger.error("Exception", e); } finally { sendAndStateLock.unlock(); } } } private class RequestDelivery implements Runnable { ClientCCASession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case ReAuthAnswer.code: handleEvent(new Event(Event.Type.RECEIVED_RAR, factory.createReAuthRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failure processing request", e); } } } private class AnswerDelivery implements Runnable { ClientCCASession session; Answer answer; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case JCreditControlAnswer.code: JCreditControlRequest _request = factory.createCreditControlRequest(request); JCreditControlAnswer _answer = factory.createCreditControlAnswer(answer); extractFHAVPs(null, _answer); handleEvent(new Event(false, _request, _answer)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failure processing success message", e); } } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ClientCCASessionImpl other = (ClientCCASessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cca/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.cca; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { public enum Type { SEND_INITIAL_REQUEST, RECEIVED_INITIAL_ANSWER, SEND_UPDATE_REQUEST, RECEIVED_UPDATE_ANSWER, SEND_TERMINATE_REQUEST, RECEIVED_TERMINATED_ANSWER, RECEIVED_RAR, SEND_RAA, Tx_TIMER_FIRED, SEND_EVENT_REQUEST, RECEIVE_EVENT_ANSWER; } Type type; AppRequestEvent request; AppAnswerEvent answer; Event(Type type) { this.type = type; } Event(Type type, AppRequestEvent request, AppAnswerEvent answer) { this.type = type; this.answer = answer; this.request = request; } Event(boolean isRequest, JCreditControlRequest request, JCreditControlAnswer answer) { this.answer = answer; this.request = request; if (isRequest) { switch (request.getRequestTypeAVPValue()) { case 1: type = Type.SEND_INITIAL_REQUEST; break; case 2: type = Type.SEND_UPDATE_REQUEST; break; case 3: type = Type.SEND_TERMINATE_REQUEST; break; case 4: type = Type.SEND_EVENT_REQUEST; break; default: throw new RuntimeException("Wrong CC-Request-Type value: " + request.getRequestTypeAVPValue()); } } else { switch (answer.getRequestTypeAVPValue()) { case 1: type = Type.RECEIVED_INITIAL_ANSWER; break; case 2: type = Type.RECEIVED_UPDATE_ANSWER; break; case 3: type = Type.RECEIVED_TERMINATED_ANSWER; break; case 4: type = Type.RECEIVE_EVENT_ANSWER; break; default: throw new RuntimeException("Wrong CC-Request-Type value: " + answer.getRequestTypeAVPValue()); } } } @Override public Enum getType() { return type; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { // FIXME: What should we do here?! Is it request or answer? } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public E encodeType(Class eClass) { return eClass == Event.Type.class ? (E) type : null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cca/IClientCCASessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.cca; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.cca.ClientCCASessionState; import org.jdiameter.common.api.app.cca.ICCASessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientCCASessionData extends ICCASessionData { boolean isEventBased(); void setEventBased(boolean b); boolean isRequestTypeSet(); void setRequestTypeSet(boolean b); ClientCCASessionState getClientCCASessionState(); void setClientCCASessionState(ClientCCASessionState state); Serializable getTxTimerId(); void setTxTimerId(Serializable txTimerId); Request getTxTimerRequest(); void setTxTimerRequest(Request txTimerRequest); Request getBuffer(); void setBuffer(Request buffer); int getGatheredRequestedAction(); void setGatheredRequestedAction(int gatheredRequestedAction); int getGatheredCCFH(); void setGatheredCCFH(int gatheredCCFH); int getGatheredDDFH(); void setGatheredDDFH(int gatheredDDFH); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cxdx/ClientCxDxSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.cxdx; import org.jdiameter.common.impl.app.cxdx.CxDxLocalSessionDataImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientCxDxSessionDataLocalImpl extends CxDxLocalSessionDataImpl implements IClientCxDxSessionData { /** * */ public ClientCxDxSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cxdx/CxDxClientSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.cxdx; import org.jdiameter.api.*; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.cxdx.ClientCxDxSession; import org.jdiameter.api.cxdx.ClientCxDxSessionListener; import org.jdiameter.api.cxdx.events.*; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.cxdx.Event.Type; import org.jdiameter.common.api.app.cxdx.CxDxSessionState; import org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.cxdx.CxDxSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Diameter Cx/Dx Client Session implementation * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class CxDxClientSessionImpl extends CxDxSession implements ClientCxDxSession, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(CxDxClientSessionImpl.class); // Factories and Listeners -------------------------------------------------- private transient ClientCxDxSessionListener listener; protected long appId = -1; protected IClientCxDxSessionData sessionData; public CxDxClientSessionImpl(IClientCxDxSessionData sessionData, ICxDxMessageFactory fct, ISessionFactory sf, ClientCxDxSessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationId() < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.appId = fct.getApplicationId(); this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } public void setListener(ClientCxDxSessionListener listener) { this.listener = listener; } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateMachine#getState(java.lang.Class) */ @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == CxDxSessionState.class ? (E) this.sessionData.getCxDxSessionState() : null; } /* * (non-Javadoc) * * @see org.jdiameter.api.NetworkReqListener#processRequest(org.jdiameter.api.Request) */ @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ClientCxDxSession#sendLocationInformationRequest(org.jdiameter.api.cxdx.events. * JLocationInfoRequest) */ @Override public void sendLocationInformationRequest(JLocationInfoRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } /* * (non-Javadoc) * * @see * org.jdiameter.api.cxdx.ClientCxDxSession#sendMultimediaAuthRequest(org.jdiameter.api.cxdx.events.JMultimediaAuthRequest) */ @Override public void sendMultimediaAuthRequest(JMultimediaAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ClientCxDxSession#sendServerAssignmentRequest(org.jdiameter.api.cxdx.events. * JServerAssignmentRequest) */ @Override public void sendServerAssignmentRequest(JServerAssignmentRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ClientCxDxSession#sendUserAuthorizationRequest(org.jdiameter.api.cxdx.events. * JUserAuthorizationRequest) */ @Override public void sendUserAuthorizationRequest(JUserAuthorizationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ClientCxDxSession#sendPushProfileAnswer(org.jdiameter.api.cxdx.events.JPushProfileAnswer) */ @Override public void sendPushProfileAnswer(JPushProfileAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ClientCxDxSession#sendRegistrationTerminationAnswer(org.jdiameter.api.cxdx.events. * JRegistrationTerminationAnswer) */ @Override public void sendRegistrationTerminationAnswer(JRegistrationTerminationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } /* * (non-Javadoc) * * @see org.jdiameter.api.EventListener#receivedSuccessMessage(org.jdiameter.api.Message, org.jdiameter.api.Message) */ @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } /* * (non-Javadoc) * * @see * org.jdiameter.api.EventListener#timeoutExpired(org.jdiameter.api.Message) */ @Override public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final CxDxSessionState state = this.sessionData.getCxDxSessionState(); CxDxSessionState newState = null; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVE_PPR: //super.scheduler.schedule(new TimeoutTimerTask((Request) ((AppEvent) event.getData()).getMessage()), CxDxSession._TX_TIMEOUT, TimeUnit.MILLISECONDS); this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.startMsgTimer(); newState = CxDxSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doPushProfileRequest(this, (JPushProfileRequest) event.getData()); break; case RECEIVE_RTR: //super.scheduler.schedule(new TimeoutTimerTask((Request) ((AppEvent) event.getData()).getMessage()), CxDxSession._TX_TIMEOUT, TimeUnit.MILLISECONDS); newState = CxDxSessionState.MESSAGE_SENT_RECEIVED; setState(newState); this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.startMsgTimer(); listener.doRegistrationTerminationRequest(this, (JRegistrationTerminationRequest) event.getData()); break; case SEND_MESSAGE: newState = CxDxSessionState.MESSAGE_SENT_RECEIVED; super.session.send(((AppEvent) event.getData()).getMessage(), this); setState(newState); //FIXME: is this ok to be here? break; default: logger.error("Invalid Event Type {} for Cx/Dx Client Session at state {}.", eventType, sessionData.getCxDxSessionState()); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = CxDxSessionState.TIMEDOUT; setState(newState); break; case SEND_MESSAGE: // if (super.timeoutTaskFuture != null) { // super.timeoutTaskFuture.cancel(false); // super.timeoutTaskFuture = null; // } super.session.send(((AppEvent) event.getData()).getMessage(), this); newState = CxDxSessionState.TERMINATED; setState(newState); break; case RECEIVE_LIA: newState = CxDxSessionState.TERMINATED; setState(newState); super.cancelMsgTimer(); listener.doLocationInformationAnswer(this, null, (JLocationInfoAnswer) event.getData()); break; case RECEIVE_MAA: newState = CxDxSessionState.TERMINATED; setState(newState); super.cancelMsgTimer(); listener.doMultimediaAuthAnswer(this, null, (JMultimediaAuthAnswer) event.getData()); break; case RECEIVE_SAA: newState = CxDxSessionState.TERMINATED; setState(newState); super.cancelMsgTimer(); listener.doServerAssignmentAnswer(this, null, (JServerAssignmentAnswer) event.getData()); break; case RECEIVE_UAA: newState = CxDxSessionState.TERMINATED; setState(newState); super.cancelMsgTimer(); listener.doUserAuthorizationAnswer(this, null, (JUserAuthorizationAnswer) event.getData()); break; default: throw new InternalException( "Should not receive more messages after initial. Command: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("Cx/Dx Client FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } @SuppressWarnings("unchecked") protected void setState(CxDxSessionState newState) { CxDxSessionState oldState = this.sessionData.getCxDxSessionState(); this.sessionData.setCxDxSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == CxDxSessionState.TERMINATED || newState == CxDxSessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); // if (super.timeoutTaskFuture != null) { // timeoutTaskFuture.cancel(true); // timeoutTaskFuture = null; // } } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(CxDxSession.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (int) (appId ^ (appId >>> 32)); return result; } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } CxDxClientSessionImpl other = (CxDxClientSessionImpl) obj; if (appId != other.appId) { return false; } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ClientCxDxSession session; Request request; @Override public void run() { try { if (request.getCommandCode() == JRegistrationTerminationRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_RTR, messageFactory.createRegistrationTerminationRequest(request), null)); } else if (request.getCommandCode() == JPushProfileRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_PPR, messageFactory.createPushProfileRequest(request), null)); } else { listener.doOtherEvent(session, new AppRequestEventImpl(request), null); } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ClientCxDxSession session; Answer answer; Request request; @Override public void run() { try { switch (answer.getCommandCode()) { case JUserAuthorizationAnswer.code: handleEvent( new Event(Event.Type.RECEIVE_UAA, null, messageFactory.createUserAuthorizationAnswer(answer))); break; case JServerAssignmentAnswer.code: handleEvent( new Event(Event.Type.RECEIVE_SAA, null, messageFactory.createServerAssignmentAnswer(answer))); break; case JMultimediaAuthAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_MAA, null, messageFactory.createMultimediaAuthAnswer(answer))); break; case JLocationInfoAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_LIA, null, messageFactory.createLocationInfoAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cxdx/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.cxdx; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, RECEIVE_RTR, RECEIVE_PPR, TIMEOUT_EXPIRES, RECEIVE_UAA, RECEIVE_SAA, RECEIVE_LIA, RECEIVE_MAA; } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { // TODO: Replace Request/Answer with this } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/cxdx/IClientCxDxSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.cxdx; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientCxDxSessionData extends ICxDxSessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/gq/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.gq; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Yulian Oifa * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class Event implements StateEvent { enum Type { SEND_AUTH_REQUEST, SEND_AUTH_ANSWER, SEND_SESSION_TERMINATION_REQUEST, SEND_SESSION_ABORT_ANSWER, RECEIVE_AUTH_ANSWER, RECEIVE_FAILED_AUTH_ANSWER, RECEIVE_ABORT_SESSION_REQUEST, RECEIVE_SESSION_TERINATION_ANSWER, TIMEOUT_EXPIRES } Type type; AppEvent data; Event(Type type, AppEvent data) { this.type = type; this.data = data; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public void setData(Object o) { data = (AppEvent) o; } @Override public Object getData() { return data; } @Override public int compareTo(Object o) { return 0; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/gq/GqClientSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.gq; import org.jdiameter.api.*; import org.jdiameter.api.app.*; import org.jdiameter.api.auth.ClientAuthSessionListener; import org.jdiameter.api.auth.events.*; import org.jdiameter.api.gq.GqClientSession; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.auth.IClientAuthSessionData; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.auth.ClientAuthSessionState; import org.jdiameter.common.api.app.auth.IAuthMessageFactory; import org.jdiameter.common.api.app.auth.IClientAuthActionContext; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.auth.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import static org.jdiameter.api.Message.SESSION_TERMINATION_REQUEST; import static org.jdiameter.common.api.app.auth.ClientAuthSessionState.*; /** * Client Gq Application session implementation * * @author Yulian Oifa * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class GqClientSessionImpl extends AppAuthSessionImpl implements GqClientSession, EventListener, NetworkReqListener { protected static final Logger logger = LoggerFactory.getLogger(GqClientSessionImpl.class); // Session State Handling --------------------------------------------------- protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IAuthMessageFactory factory; protected transient IClientAuthActionContext context; protected transient ClientAuthSessionListener listener; protected static final String TIMER_NAME_TS = "GQ_TS"; protected IClientAuthSessionData sessionData; // Constructors ------------------------------------------------------------- public GqClientSessionImpl(IClientAuthSessionData sessionData, ISessionFactory sf, ClientAuthSessionListener lst, IAuthMessageFactory fct, StateChangeListener scListener, IClientAuthActionContext context, boolean stateless) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationId() == null) { throw new IllegalArgumentException("ApplicationId can not be null"); } super.appId = fct.getApplicationId(); this.listener = lst; this.factory = fct; this.context = context; this.sessionData = sessionData; this.sessionData.setStateless(stateless); super.addStateChangeNotification(scListener); } public void setListener(ClientAuthSessionListener listener) { this.listener = listener; } // ClientAuthSession Implementation methods --------------------------------- @Override public void sendAbortSessionAnswer(AbortSessionAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_SESSION_ABORT_ANSWER, answer); } @Override public void sendAuthRequest(AppRequestEvent request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_AUTH_REQUEST, request); } @Override public void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_AUTH_ANSWER, answer); } @Override public void sendSessionTerminationRequest(SessionTermRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_SESSION_TERMINATION_REQUEST, request); } protected void send(Event.Type type, AppEvent event) throws InternalException { //This is called from app thread, it may be due to callback from our delivery thread, but we dont care try { sendAndStateLock.lock(); if (type != null) { handleEvent(new Event(type, event)); } session.send(event.getMessage(), this); // Store last destination information AvpSet avps = event.getMessage().getAvps(); Avp destRealmAvp = avps.getAvp(Avp.DESTINATION_REALM); if (destRealmAvp != null) { sessionData.setDestinationRealm(destRealmAvp.getDiameterIdentity()); } Avp destHostAvp = avps.getAvp(Avp.DESTINATION_HOST); if (destHostAvp != null) { sessionData.setDestinationHost(destHostAvp.getDiameterIdentity()); } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } @Override public boolean isStateless() { return this.sessionData.isStateless(); } @SuppressWarnings("unchecked") protected void setState(ClientAuthSessionState newState) { IAppSessionState oldState = sessionData.getClientAuthSessionState(); sessionData.setClientAuthSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } } @Override @SuppressWarnings("unchecked") public E getState(Class eClass) { return eClass == ClientAuthSessionState.class ? (E) sessionData.getClientAuthSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return sessionData.isStateless() ? handleEventForStatelessSession(event) : handleEventForStatefulSession(event); } public boolean handleEventForStatelessSession(StateEvent event) throws InternalException, OverloadException { try { ClientAuthSessionState state = sessionData.getClientAuthSessionState(); ClientAuthSessionState oldState = state; switch (state) { case IDLE: switch ((Event.Type) event.getType()) { case SEND_AUTH_REQUEST: // Current State: IDLE // Event: Client or Device Requests access // Action: Send service specific auth req // New State: PENDING setState(PENDING); break; default: logger.debug("Unknown event [{}]", event.getType()); break; } break; case PENDING: switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_ANSWER: try { // Current State: PENDING // Event: Successful service-specific authorization answer received with Auth-Session-State set to NO_STATE_MAINTAINED // Action: Grant Access // New State: OPEN listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData()); setState(OPEN); } catch (Exception e) { // Current State: PENDING // Event: Failed service-specific authorization answer received // Action: Cleanup // New State: IDLE setState(IDLE); } break; case SEND_SESSION_TERMINATION_REQUEST: // Current State: OPEN // Event: Service to user is terminated // Action: Disconnect User/Device // New State: IDLE setState(IDLE); break; default: logger.debug("Unknown event [{}]", event.getType()); break; } break; case OPEN: switch ((Event.Type) event.getType()) { case SEND_SESSION_ABORT_ANSWER: case SEND_SESSION_TERMINATION_REQUEST: // Current State: OPEN // Event: Service to user is terminated // Action: Disconnect User/Device // New State: IDLE setState(IDLE); break; case TIMEOUT_EXPIRES: // Current State: OPEN // Event: Session-Timeout Expires on Access Device // Action: Send STR // New State: DISCON if (context != null) { context.accessTimeoutElapses(this); Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } // IDLE is the same as DISCON setState(IDLE); break; default: logger.debug("Unknown event [{}]", event.getType()); break; } break; } // post processing if (oldState != state) { if (DISCONNECTED.equals(state) || IDLE.equals(state)) { cancelTsTimer(); } else if (OPEN.equals(state) && context != null && context.getAccessTimeout() > 0) { cancelTsTimer(); startTsTimer(); } } } catch (Throwable t) { throw new InternalException(t); } return true; } public boolean handleEventForStatefulSession(StateEvent event) throws InternalException, OverloadException { ClientAuthSessionState state = sessionData.getClientAuthSessionState(); ClientAuthSessionState oldState = state; try { switch (state) { case IDLE: { switch ((Event.Type) event.getType()) { case SEND_AUTH_REQUEST: // Current State: IDLE // Event: Client or Device Requests access // Action: Send service specific auth req // New State: PENDING setState(PENDING); break; case RECEIVE_ABORT_SESSION_REQUEST: // Current State: IDLE // Event: ASR Received for unknown session // Action: Send ASA with Result-Code = UNKNOWN_SESSION_ID // New State: IDLE // FIXME: Should send ASA with UNKNOWN_SESSION_ID instead ? listener.doAbortSessionRequestEvent(this, (AbortSessionRequest) event.getData()); break; default: logger.debug("Unknown event [{}]", event.getType()); break; } break; } case PENDING: { switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_ANSWER: try { // Current State: PENDING // Event: Successful service-specific authorization answer received with default Auth-Session-State value // Action: Grant Access // New State: OPEN listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData()); setState(OPEN); } catch (InternalException e) { // Current State: PENDING // Event: Successful service-specific authorization answer received but service not provided // Action: Send STR // New State: DISCON // Current State: PENDING // Event: Error Processing successful service-specific authorization answer // Action: Send STR // New State: DISCON setState(DISCONNECTED); } catch (Exception e) { // Current State: PENDING // Event: Failed service-specific authorization answer received // Action: Cleanup // New State: IDLE setState(IDLE); } break; case SEND_SESSION_TERMINATION_REQUEST: // Current State: OPEN // Event: Service to user is terminated // Action: Disconnect User/Device // New State: IDLE setState(DISCONNECTED); break; default: logger.debug("Unknown event [{}]", event.getType()); break; } break; } case OPEN: { switch ((Event.Type) event.getType()) { case SEND_AUTH_REQUEST: // Current State: OPEN // Event: User or client device requests access to service // Action: Send service specific auth req // New State: OPEN break; case RECEIVE_AUTH_ANSWER: try { // Current State: OPEN // Event: Successful service-specific authorization answer received // Action: Provide Service // New State: OPEN listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData()); } catch (Exception e) { // Current State: OPEN // Event: ASR Received, client will comply with request to end the session // Action: Send ASA with Result-Code = SUCCESS, Send STR // New State: DISCON setState(DISCONNECTED); } break; case RECEIVE_FAILED_AUTH_ANSWER: // Current State: OPEN // Event: Failed Service-specific authorization answer received // Action: Disconnect User/Device // New State: IDLE if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } setState(IDLE); break; case RECEIVE_ABORT_SESSION_REQUEST: // Current State: OPEN // Event: ASR Received (client to take comply or not) // Action: TBD // New State: TBD (comply = DISCON, !comply = OPEN) listener.doAbortSessionRequestEvent(this, (AbortSessionRequestImpl) event.getData()); break; case SEND_SESSION_TERMINATION_REQUEST: setState(DISCONNECTED); break; case TIMEOUT_EXPIRES: // Current State: OPEN // Event: Session-Timeout Expires on Access Device // Action: Send STR // New State: DISCON // Current State: OPEN // Event: Authorization-Lifetime + Auth-Grace-Period expires on access device // Action: Send STR // New State: DISCON if (context != null) { context.accessTimeoutElapses(this); Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } setState(DISCONNECTED); break; } break; } case DISCONNECTED: { switch ((Event.Type) event.getType()) { case RECEIVE_ABORT_SESSION_REQUEST: // Current State: DISCON // Event: ASR Received // Action: Send ASA // New State: DISCON listener.doAbortSessionRequestEvent(this, (AbortSessionRequest) event.getData()); break; case RECEIVE_SESSION_TERINATION_ANSWER: // Current State: DISCON // Event: STA Received // Action: Disconnect User/Device // New State: IDLE listener.doSessionTerminationAnswerEvent(this, ((SessionTermAnswerImpl) event.getData())); setState(IDLE); break; default: logger.debug("Unknown event [{}]", event.getType()); break; } break; } default: { logger.debug("Unknown state [{}]", state); break; } } // post processing if (oldState != state) { if (OPEN.equals(state) && context != null && context.getAccessTimeout() > 0) { cancelTsTimer(); startTsTimer(); } } } catch (Throwable t) { throw new InternalException(t); } return true; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery ad = new AnswerDelivery(); ad.session = this; ad.request = request; ad.answer = answer; super.scheduler.execute(ad); } @Override public void timeoutExpired(Request request) { try { //FIXME: should this also be async ? handleEvent(new Event(Event.Type.RECEIVE_FAILED_AUTH_ANSWER, new AppRequestEventImpl(request))); } catch (Exception e) { logger.debug("Can not handle timeout event", e); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } protected void startTsTimer() throws IllegalArgumentException, InternalException { try { sendAndStateLock.lock(); sessionData.setTsTimerId( super.timerFacility.schedule(sessionData.getSessionId(), TIMER_NAME_TS, context.getAccessTimeout())); } finally { sendAndStateLock.unlock(); } } protected void cancelTsTimer() { try { sendAndStateLock.lock(); Serializable timerId = sessionData.getTsTimerId(); if (timerId != null) { super.timerFacility.cancel(timerId); sessionData.setTsTimerId(null); } } finally { sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TIMER_NAME_TS)) { try { sendAndStateLock.lock(); sessionData.setTsTimerId(null); if (context != null) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, null)); } catch (Exception e) { logger.debug("Can not handle event", e); } } } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } protected AbortSessionAnswer createAbortSessionAnswer(Answer answer) { return new AbortSessionAnswerImpl(answer); } protected AbortSessionRequest createAbortSessionRequest(Request request) { return new AbortSessionRequestImpl(request); } protected ReAuthAnswer createReAuthAnswer(Answer answer) { return new ReAuthAnswerImpl(answer); } protected ReAuthRequest createReAuthRequest(Request request) { return new ReAuthRequestImpl(request); } protected SessionTermAnswer createSessionTermAnswer(Answer answer) { return new SessionTermAnswerImpl(answer); } protected SessionTermRequest createSessionTermRequest(Request request) { return new SessionTermRequestImpl(request); } protected Request createSessionTermRequest() { return session.createRequest(SESSION_TERMINATION_REQUEST, appId, sessionData.getDestinationRealm(), sessionData.getDestinationHost()); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } GqClientSessionImpl other = (GqClientSessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } private class RequestDelivery implements Runnable { GqClientSession session; Request request; @Override public void run() { try { if (request.getCommandCode() == AbortSessionRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_ABORT_SESSION_REQUEST, createAbortSessionRequest(request))); } else if (request.getCommandCode() == ReAuthRequest.code) { listener.doReAuthRequestEvent(session, createReAuthRequest(request)); } else { listener.doOtherEvent(session, factory.createAuthRequest(request), null); } } catch (Exception e) { logger.debug("Can not process received request", e); } } } private class AnswerDelivery implements Runnable { GqClientSession session; Answer answer; Request request; @Override public void run() { try { sendAndStateLock.lock(); // FIXME: baranowb: this shouldn't be like that? if (answer.getCommandCode() == factory.getAuthMessageCommandCode()) { handleEvent(new Event(Event.Type.RECEIVE_AUTH_ANSWER, factory.createAuthAnswer(answer))); } else if (answer.getCommandCode() == SessionTermAnswer.code) { handleEvent(new Event(Event.Type.RECEIVE_SESSION_TERINATION_ANSWER, createSessionTermAnswer(answer))); } else { listener.doOtherEvent(session, factory.createAuthRequest(request), new AppAnswerEventImpl(answer)); } } catch (Exception e) { logger.debug("Can not process received message", e); } finally { sendAndStateLock.unlock(); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/gx/ClientGxSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.gx; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.gx.ClientGxSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientGxSessionDataLocalImpl extends AppSessionDataLocalImpl implements IClientGxSessionData { protected boolean isEventBased = true; protected boolean requestTypeSet = false; protected ClientGxSessionState state = ClientGxSessionState.IDLE; protected Serializable txTimerId; //protected JCreditControlRequest txTimerRequest; protected Request txTimerRequest; // Event Based Buffer //protected Message buffer = null; protected Request buffer; protected int gatheredRequestedAction = NON_INITIALIZED; protected int gatheredCCFH = NON_INITIALIZED; protected int gatheredDDFH = NON_INITIALIZED; /** * */ public ClientGxSessionDataLocalImpl() { } @Override public boolean isEventBased() { return isEventBased; } @Override public void setEventBased(boolean isEventBased) { this.isEventBased = isEventBased; } @Override public boolean isRequestTypeSet() { return requestTypeSet; } @Override public void setRequestTypeSet(boolean requestTypeSet) { this.requestTypeSet = requestTypeSet; } @Override public ClientGxSessionState getClientGxSessionState() { return state; } @Override public void setClientGxSessionState(ClientGxSessionState state) { this.state = state; } @Override public Serializable getTxTimerId() { return txTimerId; } @Override public void setTxTimerId(Serializable txTimerId) { this.txTimerId = txTimerId; } @Override public Request getTxTimerRequest() { return txTimerRequest; } @Override public void setTxTimerRequest(Request txTimerRequest) { this.txTimerRequest = txTimerRequest; } @Override public Request getBuffer() { return buffer; } @Override public void setBuffer(Request buffer) { this.buffer = buffer; } @Override public int getGatheredRequestedAction() { return gatheredRequestedAction; } @Override public void setGatheredRequestedAction(int gatheredRequestedAction) { this.gatheredRequestedAction = gatheredRequestedAction; } @Override public int getGatheredCCFH() { return gatheredCCFH; } @Override public void setGatheredCCFH(int gatheredCCFH) { this.gatheredCCFH = gatheredCCFH; } @Override public int getGatheredDDFH() { return gatheredDDFH; } @Override public void setGatheredDDFH(int gatheredDDFH) { this.gatheredDDFH = gatheredDDFH; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/gx/ClientGxSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.gx; import org.jdiameter.api.*; import org.jdiameter.api.app.*; import org.jdiameter.api.gx.ClientGxSession; import org.jdiameter.api.gx.ClientGxSessionListener; import org.jdiameter.api.gx.events.GxCreditControlAnswer; import org.jdiameter.api.gx.events.GxCreditControlRequest; import org.jdiameter.api.gx.events.GxReAuthAnswer; import org.jdiameter.api.gx.events.GxReAuthRequest; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.app.gx.Event.Type; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.gx.ClientGxSessionState; import org.jdiameter.common.api.app.gx.IClientGxSessionContext; import org.jdiameter.common.api.app.gx.IGxMessageFactory; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.gx.AppGxSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Client Credit-Control Application session implementation * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public class ClientGxSessionImpl extends AppGxSessionImpl implements ClientGxSession, NetworkReqListener, EventListener { private static final Logger logger = LoggerFactory.getLogger(ClientGxSessionImpl.class); protected IClientGxSessionData sessionData; // Session State Handling --------------------------------------------------- protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected IGxMessageFactory factory; protected ClientGxSessionListener listener; protected IClientGxSessionContext context; protected IMessageParser parser; // Tx Timer ----------------------------------------------------------------- protected static final String TX_TIMER_NAME = "Gx_CLIENT_TX_TIMER"; protected static final long TX_TIMER_DEFAULT_VALUE = 30 * 60 * 1000; // miliseconds protected long[] authAppIds = new long[]{4}; protected static final int CCFH_TERMINATE = 0; protected static final int CCFH_CONTINUE = 1; protected static final int CCFH_RETRY_AND_TERMINATE = 2; private static final int DDFH_TERMINATE_OR_BUFFER = 0; private static final int DDFH_CONTINUE = 1; // CC-Request-Type Values --------------------------------------------------- private static final int DIRECT_DEBITING = 0; private static final int REFUND_ACCOUNT = 1; private static final int CHECK_BALANCE = 2; private static final int PRICE_ENQUIRY = 3; private static final int EVENT_REQUEST = 4; // Error Codes -------------------------------------------------------------- private static final long END_USER_SERVICE_DENIED = 4010; private static final long CREDIT_CONTROL_NOT_APPLICABLE = 4011; private static final long USER_UNKNOWN = 5030; private static final long DIAMETER_UNABLE_TO_DELIVER = 3002L; private static final long DIAMETER_TOO_BUSY = 3004L; private static final long DIAMETER_LOOP_DETECTED = 3005L; protected static final Set temporaryErrorCodes; static { HashSet tmp = new HashSet(); tmp.add(DIAMETER_UNABLE_TO_DELIVER); tmp.add(DIAMETER_TOO_BUSY); tmp.add(DIAMETER_LOOP_DETECTED); temporaryErrorCodes = Collections.unmodifiableSet(tmp); } // Session Based Queue protected ArrayList eventQueue = new ArrayList(); public ClientGxSessionImpl(IClientGxSessionData sessionData, IGxMessageFactory fct, ISessionFactory sf, ClientGxSessionListener lst, IClientGxSessionContext ctx, StateChangeListener stLst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationIds() == null) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.context = ctx; this.authAppIds = fct.getApplicationIds(); this.listener = lst; this.factory = fct; IContainer icontainer = sf.getContainer(); this.parser = icontainer.getAssemblerFacility().getComponentInstance(IMessageParser.class); this.sessionData = sessionData; super.addStateChangeNotification(stLst); } public void setListener(ClientGxSessionListener listener) { this.listener = listener; } protected int getLocalCCFH() { return this.sessionData.getGatheredCCFH() >= 0 ? this.sessionData.getGatheredCCFH() : context.getDefaultCCFHValue(); } protected int getLocalDDFH() { return this.sessionData.getGatheredDDFH() >= 0 ? this.sessionData.getGatheredDDFH() : context.getDefaultDDFHValue(); } @Override public void sendCreditControlRequest(GxCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { try { extractFHAVPs(request, null); this.handleEvent(new Event(true, request, null)); } catch (AvpDataException e) { throw new InternalException(e); } } @Override public void sendGxReAuthAnswer(GxReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { this.handleEvent(new Event(Event.Type.SEND_RAA, null, answer)); } @Override public boolean isStateless() { return false; } public boolean isEventBased() { return this.sessionData.isEventBased(); } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == ClientGxSessionState.class ? (E) this.sessionData.getClientGxSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return this.isEventBased() ? handleEventForEventBased(event) : handleEventForSessionBased(event); } protected boolean handleEventForEventBased(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); final ClientGxSessionState state = this.sessionData.getClientGxSessionState(); Event localEvent = (Event) event; Event.Type eventType = (Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case SEND_EVENT_REQUEST: // Current State: IDLE // Event: Client or device requests a one-time service // Action: Send CC event request, start Tx // New State: PENDING_E startTx((GxCreditControlRequest) localEvent.getRequest()); setState(ClientGxSessionState.PENDING_EVENT); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table logger.debug("Failure handling send event request", e); handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_EVENT: switch (eventType) { case RECEIVE_EVENT_ANSWER: AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer(); try { long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_E // Event: Successful CC event answer received // Action: Grant service to end user // New State: IDLE setState(ClientGxSessionState.IDLE, false); } if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((GxCreditControlAnswer) answer, (GxCreditControlRequest) localEvent.getRequest(), eventType); } deliverGxAnswer((GxCreditControlRequest) localEvent.getRequest(), (GxCreditControlAnswer) localEvent.getAnswer()); } catch (AvpDataException e) { logger.debug("Failure handling received answer event", e); setState(ClientGxSessionState.IDLE, false); } break; case Tx_TIMER_FIRED: handleTxExpires(localEvent.getRequest().getMessage()); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_BUFFERED: switch (eventType) { case RECEIVE_EVENT_ANSWER: // Current State: PENDING_B // Event: Successful CC answer received // Action: Delete request // New State: IDLE setState(ClientGxSessionState.IDLE, false); this.sessionData.setBuffer(null); deliverGxAnswer((GxCreditControlRequest) localEvent.getRequest(), (GxCreditControlAnswer) localEvent.getAnswer()); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } dispatch(); return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } protected boolean handleEventForSessionBased(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); final ClientGxSessionState state = this.sessionData.getClientGxSessionState(); final Event localEvent = (Event) event; final Event.Type eventType = (Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case SEND_INITIAL_REQUEST: // Current State: IDLE // Event: Client or device requests access/service // Action: Send CC initial request, start Tx // New State: PENDING_I startTx((GxCreditControlRequest) localEvent.getRequest()); setState(ClientGxSessionState.PENDING_INITIAL); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_INITIAL: AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVED_INITIAL_ANSWER: long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_I // Event: Successful CC initial answer received // Action: Stop Tx // New State: OPEN stopTx(); setState(ClientGxSessionState.OPEN); } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((GxCreditControlAnswer) answer, (GxCreditControlRequest) localEvent.getRequest(), eventType); } deliverGxAnswer((GxCreditControlRequest) localEvent.getRequest(), (GxCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: handleTxExpires(localEvent.getRequest().getMessage()); break; case SEND_UPDATE_REQUEST: case SEND_TERMINATE_REQUEST: // Current State: PENDING_I // Event: User service terminated // Action: Queue termination event // New State: PENDING_I // Current State: PENDING_I // Event: Change in rating condition // Action: Queue changed rating condition event // New State: PENDING_I eventQueue.add(localEvent); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case OPEN: switch (eventType) { case SEND_UPDATE_REQUEST: // Current State: OPEN // Event: Granted unit elapses and no final unit indication received // Action: Send CC update request, start Tx // New State: PENDING_U // Current State: OPEN // Event: Change in rating condition in queue // Action: Send CC update request, start Tx // New State: PENDING_U // Current State: OPEN // Event: Change in rating condition or Validity-Time elapses // Action: Send CC update request, start Tx // New State: PENDING_U // Current State: OPEN // Event: RAR received // Action: Send RAA followed by CC update request, start Tx // New State: PENDING_U startTx((GxCreditControlRequest) localEvent.getRequest()); setState(ClientGxSessionState.PENDING_UPDATE); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case SEND_TERMINATE_REQUEST: // Current State: OPEN // Event: Granted unit elapses and final unit action equal to TERMINATE received // Action: Terminate end user�s service, send CC termination request // New State: PENDING_T // Current State: OPEN // Event: Service terminated in queue // Action: Send CC termination request // New State: PENDING_T // Current State: OPEN // Event: User service terminated // Action: Send CC termination request // New State: PENDING_T setState(ClientGxSessionState.PENDING_TERMINATION); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case RECEIVED_RAR: deliverRAR((GxReAuthRequest) localEvent.getRequest()); break; case SEND_RAA: try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_UPDATE: answer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVED_UPDATE_ANSWER: long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_U // Event: Successful CC update answer received // Action: Stop Tx // New State: OPEN stopTx(); setState(ClientGxSessionState.OPEN); } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((GxCreditControlAnswer) answer, (GxCreditControlRequest) localEvent.getRequest(), eventType); } deliverGxAnswer((GxCreditControlRequest) localEvent.getRequest(), (GxCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: handleTxExpires(localEvent.getRequest().getMessage()); break; case SEND_UPDATE_REQUEST: case SEND_TERMINATE_REQUEST: // Current State: PENDING_U // Event: User service terminated // Action: Queue termination event // New State: PENDING_U // Current State: PENDING_U // Event: Change in rating condition // Action: Queue changed rating condition event // New State: PENDING_U eventQueue.add(localEvent); break; case RECEIVED_RAR: deliverRAR((GxReAuthRequest) localEvent.getRequest()); break; case SEND_RAA: // Current State: PENDING_U // Event: RAR received // Action: Send RAA // New State: PENDING_U try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; } break; case PENDING_TERMINATION: switch (eventType) { case SEND_UPDATE_REQUEST: try { // Current State: PENDING_T // Event: Change in rating condition // Action: - // New State: PENDING_T dispatchEvent(localEvent.getRequest()); // No transition } catch (Exception e) { // This handles failure to send in PendingI state in FSM table // handleSendFailure(e, eventType); } break; case RECEIVED_TERMINATED_ANSWER: // Current State: PENDING_T // Event: Successful CC termination answer received // Action: - // New State: IDLE // Current State: PENDING_T // Event: Failure to send, temporary error, or failed answer // Action: - // New State: IDLE //FIXME: Alex broke this, setting back "true" ? //setState(ClientGxSessionState.IDLE, false); deliverGxAnswer((GxCreditControlRequest) localEvent.getRequest(), (GxCreditControlAnswer) localEvent.getAnswer()); setState(ClientGxSessionState.IDLE, true); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; default: // any other state is bad setState(ClientGxSessionState.IDLE, true); } dispatch(); return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery ad = new AnswerDelivery(); ad.session = this; ad.request = request; ad.answer = answer; super.scheduler.execute(ad); } @Override public void timeoutExpired(Request request) { if (request.getCommandCode() == GxCreditControlAnswer.code) { try { sendAndStateLock.lock(); handleSendFailure(null, null, request); } catch (Exception e) { logger.debug("Failure processing timeout message for request", e); } finally { sendAndStateLock.unlock(); } } } protected void startTx(GxCreditControlRequest request) { long txTimerValue = context.getDefaultTxTimerValue(); if (txTimerValue < 0) { txTimerValue = TX_TIMER_DEFAULT_VALUE; } stopTx(); logger.debug("Scheduling TX Timer {}", txTimerValue); //this.txFuture = scheduler.schedule(new TxTimerTask(this, request), txTimerValue, TimeUnit.SECONDS); try { this.sessionData.setTxTimerRequest((Request) request.getMessage()); } catch (Exception e) { throw new IllegalArgumentException("Failed to store request.", e); } this.sessionData.setTxTimerId(this.timerFacility.schedule(this.getSessionId(), TX_TIMER_NAME, TX_TIMER_DEFAULT_VALUE)); } protected void stopTx() { Serializable txTimerId = this.sessionData.getTxTimerId(); if (txTimerId != null) { this.timerFacility.cancel(txTimerId); this.sessionData.setTxTimerRequest(null); this.sessionData.setTxTimerId(null); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TX_TIMER_NAME)) { new TxTimerTask(this, this.sessionData.getTxTimerRequest()).run(); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } protected void setState(ClientGxSessionState newState) { setState(newState, true); } @SuppressWarnings("unchecked") protected void setState(ClientGxSessionState newState, boolean release) { try { IAppSessionState oldState = this.sessionData.getClientGxSessionState(); this.sessionData.setClientGxSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == ClientGxSessionState.IDLE) { if (release) { this.release(); } stopTx(); } } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure switching to state " + this.sessionData.getClientGxSessionState() + " (release=" + release + ")", e); } } } @Override public void release() { if (isValid()) { try { this.sendAndStateLock.lock(); this.stopTx(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void handleSendFailure(Exception e, Event.Type eventType, Message request) throws Exception { logger.debug("Failed to send message, type: {} message: {}, failure: {}", new Object[]{eventType, request, e != null ? e.getLocalizedMessage() : ""}); try { // Event Based ---------------------------------------------------------- final ClientGxSessionState state = this.sessionData.getClientGxSessionState(); if (isEventBased()) { final int gatheredRequestedAction = sessionData.getGatheredRequestedAction(); switch (state) { case PENDING_EVENT: if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE setState(ClientGxSessionState.IDLE); context.indicateServiceError(this); } else if (gatheredRequestedAction == DIRECT_DEBITING) { switch (getLocalDDFH()) { case DDFH_TERMINATE_OR_BUFFER: // Current State: PENDING_E // Event: Failure to send; request action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER // Action: Store request with T-flag // New State: IDLE request.setReTransmitted(true); this.sessionData.setBuffer((Request) request); setState(ClientGxSessionState.IDLE, false); break; case DDFH_CONTINUE: // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnDeliverFailure(this, request); break; default: logger.warn("Invalid Direct-Debiting-Failure-Handling AVP value {}", getLocalDDFH()); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag // New State: IDLE setState(ClientGxSessionState.IDLE, false); request.setReTransmitted(true); this.sessionData.setBuffer((Request) request); } else { logger.warn("Invalid Requested-Action AVP value {}", gatheredRequestedAction); } break; case PENDING_BUFFERED: // Current State: PENDING_B // Event: Failure to send or temporary error // Action: - // New State: IDLE setState(ClientGxSessionState.IDLE, false); this.sessionData.setBuffer(null); // FIXME: Action does not mention, but ... break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } } // Session Based -------------------------------------------------------- else { switch (getLocalCCFH()) { case CCFH_CONTINUE: // Current State: PENDING_I // Event: Failure to send, or temporary error and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE // Current State: PENDING_U // Event: Failure to send, or temporary error and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE setState(ClientGxSessionState.IDLE, false); this.context.grantAccessOnDeliverFailure(this, request); break; default: // Current State: PENDING_I // Event: Failure to send, or temporary error and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE // Action: Terminate end user�s service // New State: IDLE // Current State: PENDING_U // Event: Failure to send, or temporary error and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE // Action: Terminate end user�s service // New State: IDLE this.context.denyAccessOnDeliverFailure(this, request); setState(ClientGxSessionState.IDLE, true); break; } } } finally { dispatch(); } } protected void handleFailureMessage(final GxCreditControlAnswer event, final GxCreditControlRequest request, final Event.Type eventType) { try { // Event Based ---------------------------------------------------------- final ClientGxSessionState state = this.sessionData.getClientGxSessionState(); final Serializable txTimerId = sessionData.getTxTimerId(); final long resultCode = event.getResultCodeAvp().getUnsigned32(); if (isEventBased()) { final int gatheredRequestedAction = sessionData.getGatheredRequestedAction(); switch (state) { case PENDING_EVENT: if (resultCode == END_USER_SERVICE_DENIED || resultCode == USER_UNKNOWN) { if (sessionData.getTxTimerId() != null) { // Current State: PENDING_E // Event: CC event answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN and Tx running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverGxAnswer(request, event); setState(ClientGxSessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) { // Current State: PENDING_E // Event: Failed answer or answer received w/ result code END_USER_SERVICE DENIED or USER_UNKNOWN; requested action DIRECT_DEBITING; Tx expired // Action: - // New State: IDLE setState(ClientGxSessionState.IDLE); } } else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) { // Current State: PENDING_E // Event: CC event answer received with result code CREDIT_CONTROL_NOT_APPLICABLE; requested action DIRECT_DEBITING // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverGxAnswer(request, event); setState(ClientGxSessionState.IDLE); } else if (temporaryErrorCodes.contains(resultCode)) { if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE context.indicateServiceError(this); deliverGxAnswer(request, event); setState(ClientGxSessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverGxAnswer(request, event); setState(ClientGxSessionState.IDLE); } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverGxAnswer(request, event); setState(ClientGxSessionState.IDLE); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Temporary error, and requested action REFUND_ACCOUNT // Action: Store request // New State: IDLE this.sessionData.setBuffer((Request) request.getMessage()); setState(ClientGxSessionState.IDLE, false); } else { logger.warn( "Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } } else { // Failure if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE context.indicateServiceError(this); deliverGxAnswer(request, event); setState(ClientGxSessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverGxAnswer(request, event); setState(ClientGxSessionState.IDLE); } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverGxAnswer(request, event); setState(ClientGxSessionState.IDLE); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failed CC event answer received; requested action REFUND_ACCOUNT // Action: Indicate service error and delete request // New State: IDLE this.sessionData.setBuffer(null); context.indicateServiceError(this); deliverGxAnswer(request, event); setState(ClientGxSessionState.IDLE); } else { logger.warn( "Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } } break; case PENDING_BUFFERED: // Current State: PENDING_B // Event: Failed CC answer received // Action: Delete request // New State: IDLE this.sessionData.setBuffer(null); setState(ClientGxSessionState.IDLE, false); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); } } // Session Based -------------------------------------------------------- else { switch (state) { case PENDING_INITIAL: if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE) { // Current State: PENDING_I // Event: CC initial answer received with result code equal to CREDIT_CONTROL_NOT_APPLICABLE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientGxSessionState.IDLE, false); } else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) { // Current State: PENDING_I // Event: CC initial answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientGxSessionState.IDLE, false); } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: // Current State: PENDING_I // Event: Failed CC initial answer received and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientGxSessionState.IDLE, false); break; case CCFH_TERMINATE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_I // Event: Failed CC initial answer received and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientGxSessionState.IDLE, false); break; default: logger.warn("Invalid value for CCFH: {}", getLocalCCFH()); break; } } break; case PENDING_UPDATE: if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE) { // Current State: PENDING_U // Event: CC update answer received with result code equal to CREDIT_CONTROL_NOT_APPLICABLE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientGxSessionState.IDLE, false); } else if (resultCode == END_USER_SERVICE_DENIED) { // Current State: PENDING_U // Event: CC update answer received with result code END_USER_SERVICE_DENIED // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientGxSessionState.IDLE, false); } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: // Current State: PENDING_U // Event: Failed CC update answer received and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientGxSessionState.IDLE, false); break; case CCFH_TERMINATE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_U // Event: Failed CC update answer received and CCFH equal to CONTINUE or to RETRY_AND_CONTINUE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientGxSessionState.IDLE, false); break; default: logger.warn("Invalid value for CCFH: " + getLocalCCFH()); break; } } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); } } } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug( "Failure handling failure message for Event " + event + " (" + eventType + ") and Request " + request, e); } } } protected void handleTxExpires(Message message) { // Event Based ---------------------------------------------------------- final ClientGxSessionState state = this.sessionData.getClientGxSessionState(); if (isEventBased()) { final int gatheredRequestedAction = this.sessionData.getGatheredRequestedAction(); if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE context.indicateServiceError(this); setState(ClientGxSessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING) { final int gatheredDDFH = this.sessionData.getGatheredDDFH(); if (gatheredDDFH == DDFH_TERMINATE_OR_BUFFER) { // Current State: PENDING_E // Event: Temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER; Tx expired // Action: Store request // New State: IDLE this.sessionData.setBuffer((Request) message); setState(ClientGxSessionState.IDLE, false); } else { // Current State: PENDING_E // Event: Tx expired; requested action DIRECT_DEBITING // Action: Grant service to end user // New State: PENDING_E context.grantAccessOnTxExpire(this); setState(ClientGxSessionState.PENDING_EVENT); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag // New State: IDLE message.setReTransmitted(true); this.sessionData.setBuffer((Request) message); setState(ClientGxSessionState.IDLE, false); } } // Session Based -------------------------------------------------------- else { switch (state) { case PENDING_INITIAL: switch (getLocalCCFH()) { case CCFH_CONTINUE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_I // Event: Tx expired and CCFH equal to CONTINUE or to RETRY_AND_TERMINATE // Action: Grant service to end user // New State: PENDING_I context.grantAccessOnTxExpire(this); break; case CCFH_TERMINATE: // Current State: PENDING_I // Event: Tx expired and CCFH equal to TERMINATE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnTxExpire(this); setState(ClientGxSessionState.IDLE, true); break; default: logger.warn("Invalid value for CCFH: " + getLocalCCFH()); break; } break; case PENDING_UPDATE: switch (getLocalCCFH()) { case CCFH_CONTINUE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_U // Event: Tx expired and CCFH equal to CONTINUE or to RETRY_AND_TERMINATE // Action: Grant service to end user // New State: PENDING_U context.grantAccessOnTxExpire(this); break; case CCFH_TERMINATE: // Current State: PENDING_U // Event: Tx expired and CCFH equal to TERMINATE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnTxExpire(this); setState(ClientGxSessionState.IDLE, true); break; default: logger.error("Bad value of CCFH: " + getLocalCCFH()); break; } break; default: logger.error("Unknown state (" + state + ") on txExpire"); break; } } } /** * This makes checks on queue, moves it to proper state if event there is present on Open state ;] */ protected void dispatch() { // Event Based ---------------------------------------------------------- if (isEventBased()) { // Current State: IDLE // Event: Request in storage // Action: Send stored request // New State: PENDING_B final Request buffer = this.sessionData.getBuffer(); if (buffer != null) { setState(ClientGxSessionState.PENDING_BUFFERED); try { dispatchEvent(new AppRequestEventImpl(buffer)); } catch (Exception e) { try { handleSendFailure(e, Event.Type.SEND_EVENT_REQUEST, buffer); } catch (Exception e1) { logger.error("Failure handling buffer send failure", e1); } } } } // Session Based -------------------------------------------------------- else { if (this.sessionData.getClientGxSessionState() == ClientGxSessionState.OPEN && eventQueue.size() > 0) { try { this.handleEvent(eventQueue.remove(0)); } catch (Exception e) { logger.error("Failure handling queued event", e); } } } } protected void deliverGxAnswer(GxCreditControlRequest request, GxCreditControlAnswer answer) { try { listener.doCreditControlAnswer(this, request, answer); } catch (Exception e) { logger.warn("Failure delivering Ro Answer", e); } } protected void extractFHAVPs(GxCreditControlRequest request, GxCreditControlAnswer answer) throws AvpDataException { if (answer != null) { try { if (answer.isCreditControlFailureHandlingAVPPresent()) { this.sessionData.setGatheredCCFH(answer.getCredidControlFailureHandlingAVPValue()); } } catch (Exception e) { logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e); } try { if (answer.isDirectDebitingFailureHandlingAVPPresent()) { this.sessionData.setGatheredDDFH(answer.getDirectDebitingFailureHandlingAVPValue()); } } catch (Exception e) { logger.debug("Failure trying to obtain Direct-Debit-Failure-Handling AVP value", e); } if (!sessionData.isRequestTypeSet()) { this.sessionData.setRequestTypeSet(true); // No need to check if it exists.. it must, if not fail with exception this.sessionData.setEventBased(answer.getRequestTypeAVPValue() == EVENT_REQUEST); } } else if (request != null) { try { if (request.isRequestedActionAVPPresent()) { this.sessionData.setGatheredRequestedAction(request.getRequestedActionAVPValue()); } } catch (Exception e) { logger.debug("Failure trying to obtain Request-Action AVP value", e); } if (!sessionData.isRequestTypeSet()) { this.sessionData.setRequestTypeSet(true); // No need to check if it exists.. it must, if not fail with exception this.sessionData.setEventBased(request.getRequestTypeAVPValue() == EVENT_REQUEST); } } } protected void deliverRAR(GxReAuthRequest request) { try { listener.doGxReAuthRequest(this, request); } catch (Exception e) { logger.debug("Failure delivering RAR", e); } } protected void dispatchEvent(AppEvent event) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { session.send(event.getMessage(), this); } protected boolean isProvisional(long resultCode) { return resultCode >= 1000 && resultCode < 2000; } protected boolean isSuccess(long resultCode) { return resultCode >= 2000 && resultCode < 3000; } protected boolean isFailure(long code) { return (!isProvisional(code) && !isSuccess(code) && ((code >= 3000 && code < 6000)) && !temporaryErrorCodes.contains(code)); } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } private class TxTimerTask implements Runnable { private ClientGxSession session = null; private Request request = null; private TxTimerTask(ClientGxSession session, Request request) { super(); this.session = session; this.request = request; } @Override public void run() { try { sendAndStateLock.lock(); logger.debug("Fired TX Timer"); sessionData.setTxTimerId(null); sessionData.setTxTimerRequest(null); //?? try { context.txTimerExpired(session); } catch (Exception e) { logger.debug("Failure handling TX Timer Expired", e); } GxCreditControlRequest req = factory.createCreditControlRequest(request); handleEvent(new Event(Event.Type.Tx_TIMER_FIRED, req, null)); } catch (InternalException e) { logger.error("Internal Exception", e); } catch (OverloadException e) { logger.error("Overload Exception", e); } catch (Exception e) { logger.error("Exception", e); } finally { sendAndStateLock.unlock(); } } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } ClientGxSessionImpl other = (ClientGxSessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } private class RequestDelivery implements Runnable { ClientGxSession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case GxReAuthAnswer.code: handleEvent(new Event(Event.Type.RECEIVED_RAR, factory.createGxReAuthRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failure processing request", e); } } } private class AnswerDelivery implements Runnable { ClientGxSession session; Answer answer; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case GxCreditControlAnswer.code: final GxCreditControlRequest myRequest = factory.createCreditControlRequest(request); final GxCreditControlAnswer myAnswer = factory.createCreditControlAnswer(answer); extractFHAVPs(null, myAnswer); handleEvent(new Event(false, myRequest, myAnswer)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failure processing success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/gx/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.gx; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.gx.events.GxCreditControlAnswer; import org.jdiameter.api.gx.events.GxCreditControlRequest; /** * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { public enum Type { SEND_INITIAL_REQUEST, RECEIVED_INITIAL_ANSWER, SEND_UPDATE_REQUEST, RECEIVED_UPDATE_ANSWER, SEND_TERMINATE_REQUEST, RECEIVED_TERMINATED_ANSWER, RECEIVED_RAR, SEND_RAA, Tx_TIMER_FIRED, SEND_EVENT_REQUEST, RECEIVE_EVENT_ANSWER; } Type type; AppRequestEvent request; AppAnswerEvent answer; Event(Type type) { this.type = type; } Event(Type type, AppRequestEvent request, AppAnswerEvent answer) { this.type = type; this.answer = answer; this.request = request; } Event(boolean isRequest, GxCreditControlRequest request, GxCreditControlAnswer answer) throws AvpDataException { this.answer = answer; this.request = request; if (isRequest) { switch (request.getRequestTypeAVPValue()) { case 1: type = Type.SEND_INITIAL_REQUEST; break; case 2: type = Type.SEND_UPDATE_REQUEST; break; case 3: type = Type.SEND_TERMINATE_REQUEST; break; case 4: type = Type.SEND_EVENT_REQUEST; break; default: throw new RuntimeException("Wrong CC-Request-Type value: " + request.getRequestTypeAVPValue()); } } else { switch (answer.getRequestTypeAVPValue()) { case 1: type = Type.RECEIVED_INITIAL_ANSWER; break; case 2: type = Type.RECEIVED_UPDATE_ANSWER; break; case 3: type = Type.RECEIVED_TERMINATED_ANSWER; break; case 4: type = Type.RECEIVE_EVENT_ANSWER; break; default: throw new RuntimeException("Wrong CC-Request-Type value: " + answer.getRequestTypeAVPValue()); } } } @Override public Enum getType() { return type; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { // FIXME: What should we do here?! Is it request or answer? } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public E encodeType(Class eClass) { return eClass == Event.Type.class ? (E) type : null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/gx/IClientGxSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.gx; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.gx.ClientGxSessionState; import org.jdiameter.common.api.app.gx.IGxSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientGxSessionData extends IGxSessionData { boolean isEventBased(); void setEventBased(boolean b); boolean isRequestTypeSet(); void setRequestTypeSet(boolean b); ClientGxSessionState getClientGxSessionState(); void setClientGxSessionState(ClientGxSessionState state); Serializable getTxTimerId(); void setTxTimerId(Serializable txTimerId); Request getTxTimerRequest(); void setTxTimerRequest(Request txTimerRequest); Request getBuffer(); void setBuffer(Request buffer); int getGatheredRequestedAction(); void setGatheredRequestedAction(int gatheredRequestedAction); int getGatheredCCFH(); void setGatheredCCFH(int gatheredCCFH); int getGatheredDDFH(); void setGatheredDDFH(int gatheredDDFH); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/rf/ClientRfSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.rf; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.rf.ClientRfSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientRfSessionDataLocalImpl extends AppSessionDataLocalImpl implements IClientRfSessionData { protected boolean isEventBased = true; protected boolean requestTypeSet = false; protected ClientRfSessionState state = ClientRfSessionState.IDLE; protected Serializable tsTimerId; protected Request buffer; protected String destinationHost; protected String destinationRealm; /** * */ public ClientRfSessionDataLocalImpl() { } @Override public ClientRfSessionState getClientRfSessionState() { return state; } @Override public void setClientRfSessionState(ClientRfSessionState state) { this.state = state; } @Override public Serializable getTsTimerId() { return tsTimerId; } @Override public void setTsTimerId(Serializable txTimerId) { this.tsTimerId = txTimerId; } @Override public Request getBuffer() { return buffer; } @Override public void setBuffer(Request buffer) { this.buffer = buffer; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#getDestinationHost() */ @Override public String getDestinationHost() { return this.destinationHost; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#setDestinationHost(java.lang.String) */ @Override public void setDestinationHost(String destinationHost) { this.destinationHost = destinationHost; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#getDestinationRealm() */ @Override public String getDestinationRealm() { return this.destinationRealm; } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#setDestinationRealm(java.lang.String) */ @Override public void setDestinationRealm(String destinationRealm) { this.destinationRealm = destinationRealm; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/rf/ClientRfSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.rf; import org.jdiameter.api.*; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.rf.ClientRfSession; import org.jdiameter.api.rf.ClientRfSessionListener; import org.jdiameter.api.rf.events.RfAccountingRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.rf.ClientRfSessionState; import org.jdiameter.common.api.app.rf.IClientRfActionContext; import org.jdiameter.common.impl.app.rf.AppRfSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import static org.jdiameter.api.Avp.ACCOUNTING_REALTIME_REQUIRED; import static org.jdiameter.common.api.app.rf.ClientRfSessionState.*; /** * Client Accounting session implementation * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientRfSessionImpl extends AppRfSessionImpl implements EventListener, ClientRfSession { private static final Logger logger = LoggerFactory.getLogger(ClientRfSessionImpl.class); // Constants ---------------------------------------------------------------- public static final int DELIVER_AND_GRANT = 1; public static final int GRANT_AND_LOSE = 3; // Factories and Listeners -------------------------------------------------- protected transient IClientRfActionContext context; protected transient ClientRfSessionListener listener; protected static final String TIMER_NAME_INTERIM = "CLIENT_INTERIM"; protected IClientRfSessionData sessionData; public ClientRfSessionImpl(IClientRfSessionData sessionData, ISessionFactory sessionFactory, ClientRfSessionListener clientAccSessionListener, IClientRfActionContext iClientRfActionContext, StateChangeListener stateChangeListener, ApplicationId applicationId) { super(sessionFactory, sessionData); super.appId = applicationId; this.listener = clientAccSessionListener; this.context = iClientRfActionContext; this.sessionData = sessionData; super.addStateChangeNotification(stateChangeListener); } public void setListener(ClientRfSessionListener listener) { this.listener = listener; } @Override public void sendAccountRequest(RfAccountingRequest accountRequest) throws InternalException, IllegalStateException, RouteException, OverloadException { try { sendAndStateLock.lock(); handleEvent(new Event(accountRequest)); try { session.send(accountRequest.getMessage(), this); // Store last destination information sessionData.setDestinationRealm( accountRequest.getMessage().getAvps().getAvp(Avp.DESTINATION_REALM).getDiameterIdentity()); Avp destHostAvp = accountRequest.getMessage().getAvps().getAvp(Avp.DESTINATION_HOST); if (destHostAvp != null) { sessionData.setDestinationHost(destHostAvp.getDiameterIdentity()); } } catch (Throwable t) { logger.debug("Failed to send ACR.", t); handleEvent(new Event(Event.Type.FAILED_SEND_RECORD, accountRequest)); } } catch (Exception exc) { throw new InternalException(exc); } finally { sendAndStateLock.unlock(); } } protected synchronized void storeToBuffer(Request accountRequest) { sessionData.setBuffer(accountRequest); } protected synchronized boolean checkBufferSpace() { return sessionData.getBuffer() == null; } @SuppressWarnings("unchecked") protected void setState(IAppSessionState newState) { IAppSessionState oldState = sessionData.getClientRfSessionState(); sessionData.setClientRfSessionState((ClientRfSessionState) newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } } @Override public boolean isStateless() { return false; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { final ClientRfSessionState state = this.sessionData.getClientRfSessionState(); ClientRfSessionState oldState = state; try { switch (state) { // Idle ========== case IDLE: { switch ((Event.Type) event.getType()) { // Client or device requests access case SEND_START_RECORD: // Current State: IDLE // Event: Client or Device Requests access // Action: Send accounting start req. // New State: PENDING_S setState(PENDING_START); break; case SEND_EVENT_RECORD: // Current State: IDLE // Event: Client or device requests a one-time service // Action: Send accounting event req // New State: PENDING_E setState(PENDING_EVENT); break; // Send buffered message action in other section of this method see below default: throw new IllegalStateException("Current state " + state + " action " + event.getType()); } break; } // PendingS ========== case PENDING_START: { switch ((Event.Type) event.getType()) { case FAILED_SEND_RECORD: RfAccountingRequest request = (RfAccountingRequest) event.getData(); Avp accRtReq = request.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED); // Current State: PENDING_S // Event: Failure to send and buffer space available and realtime not equal to DELIVER_AND_GRANT // Action: Store Start Record // New State: OPEN if (checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != DELIVER_AND_GRANT) { storeToBuffer((Request) request.getMessage()); setState(OPEN); } else { // Current State: PENDING_S // Event: Failure to send and no buffer space available and realtime equal to GRANT_AND_LOSE // Action: - // New State: OPEN if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) { setState(OPEN); } else { // Current State: PENDING_S // Event: Failure to send and no buffer space available and realtime not equal to GRANT_AND_LOSE // Action: Disconnect User/Device // New State: IDLE try { if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(IDLE); } } } break; case RECEIVED_RECORD: // Current State: PENDING_S // Event: Successful accounting start answer received // Action: - // New State: OPEN processInterimIntervalAvp(event); setState(OPEN); break; case FAILED_RECEIVE_RECORD: try { RfAccountingRequest answer = (RfAccountingRequest) event.getData(); accRtReq = answer.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED); // Current State: PENDING_S // Event: Failed accounting start answer received and realtime equal to GRANT_AND_LOSE // Action: - // New State: OPEN if (accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) { setState(OPEN); } else { // Current State: PENDING_S // Event: Failed accounting start answer received and realtime not equal to GRANT_AND_LOSE // Action: Disconnect User/Device // New State: IDLE if (accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) { try { if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(IDLE); } } } } catch (Exception e) { logger.debug("Can not process answer", e); setState(IDLE); } break; case SEND_STOP_RECORD: // Current State: PENDING_S // Event: User service terminated // Action: Store stop record // New State: PENDING_S if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); storeToBuffer(str); } break; } break; } // OPEN ========== case OPEN: { switch ((Event.Type) event.getType()) { // User service terminated case SEND_STOP_RECORD: // Current State: OPEN // Event: User service terminated // Action: Send accounting stop request // New State: PENDING_L setState(PENDING_CLOSE); break; case SEND_INTERIM_RECORD: // FIXME: Shouldn't this be different ? // Current State: OPEN // Event: Interim interval elapses // Action: Send accounting interim record // New State: PENDING_I setState(PENDING_INTERIM); break; // Create timer for "Interim interval elapses" event case RECEIVED_RECORD: processInterimIntervalAvp(event); break; } } break; //FIXME: add check for abnormal // PendingI ========== case PENDING_INTERIM: { switch ((Event.Type) event.getType()) { case RECEIVED_RECORD: // Current State: PENDING_I // Event: Successful accounting interim answer received // Action: - // New State: OPEN processInterimIntervalAvp(event); setState(OPEN); break; case FAILED_SEND_RECORD: RfAccountingRequest request = (RfAccountingRequest) event.getData(); Avp accRtReq = request.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED); // Current State: PENDING_I // Event: Failure to send and buffer space available (or old record interim can be overwritten) and realtime not equal to DELIVER_AND_GRANT // Action: Store interim record // New State: OPEN if (checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != DELIVER_AND_GRANT) { storeToBuffer((Request) request.getMessage()); setState(OPEN); } else { // Current State: PENDING_I // Event: Failure to send and no buffer space available and realtime equal to GRANT_AND_LOSE // Action: - // New State: OPEN if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) { setState(OPEN); } else { // Current State: PENDING_I // Event: Failure to send and no buffer space available and realtime not equal to GRANT_AND_LOSE // Action: Disconnect User/Device // New State: IDLE if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) { try { if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(IDLE); } } } } break; case FAILED_RECEIVE_RECORD: try { RfAccountingRequest answer = (RfAccountingRequest) event.getData(); accRtReq = answer.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED); // Current State: PENDING_I // Event: Failed accounting interim answer received and realtime equal to GRANT_AND_LOSE // Action: - // New State: OPEN if (accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) { setState(OPEN); } else { // Current State: PENDING_I // Event: Failed account interim answer received and realtime not equal to GRANT_AND_LOSE // Action: Disconnect User/Device // New State: IDLE if (accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) { try { if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); session.send(str, this); } } finally { setState(IDLE); } } } } catch (Exception e) { logger.debug("Can not process received request", e); setState(IDLE); } break; case SEND_STOP_RECORD: // Current State: PENDING_I // Event: User service terminated // Action: Store stop record // New State: PENDING_I if (context != null) { Request str = createSessionTermRequest(); context.disconnectUserOrDev(this, str); storeToBuffer(str); } break; } break; } // PendingE ========== case PENDING_EVENT: { switch ((Event.Type) event.getType()) { case RECEIVED_RECORD: // Current State: PENDING_E // Event: Successful accounting event answer received // Action: - // New State: IDLE setState(IDLE); break; case FAILED_SEND_RECORD: if (checkBufferSpace()) { // Current State: PENDING_E // Event: Failure to send and buffer space available // Action: Store event record // New State: IDLE RfAccountingRequest data = (RfAccountingRequest) event.getData(); storeToBuffer((Request) data.getMessage()); } // Current State: PENDING_E // Event: Failure to send and no buffer space available // Action: - // New State: IDLE setState(IDLE); break; case FAILED_RECEIVE_RECORD: // Current State: PENDING_E // Event: Failed accounting event answer received // Action: - // New State: IDLE setState(IDLE); break; } break; } // PendingB ========== case PENDING_BUFFERED: { switch ((Event.Type) event.getType()) { case RECEIVED_RECORD: // Current State: PENDING_B // Event: Successful accounting answer received // Action: Delete record // New State: IDLE synchronized (this) { storeToBuffer(null); } setState(IDLE); break; // Failure to send case FAILED_SEND_RECORD: // Current State: PENDING_B // Event: Failure to send // Action: - // New State: IDLE setState(IDLE); break; // Failed accounting answer received case FAILED_RECEIVE_RECORD: // Current State: PENDING_B // Event: Failed accounting answer received // Action: Delete record // New State: IDLE synchronized (this) { storeToBuffer(null); } setState(IDLE); break; } break; } // PendingL ========== case PENDING_CLOSE: { switch ((Event.Type) event.getType()) { case RECEIVED_RECORD: // Current State: PENDING_L // Event: Successful accounting stop answer received // Action: - // New State: IDLE setState(IDLE); break; case FAILED_SEND_RECORD: if (checkBufferSpace()) { // Current State: PENDING_L // Event: Failure to send and buffer space available // Action: Store stop record // New State: IDLE RfAccountingRequest data = (RfAccountingRequest) event.getData(); storeToBuffer((Request) data.getMessage()); } // Current State: PENDING_L // Event: Failure to send and no buffer space available // Action: - // New State: IDLE setState(IDLE); break; // Failed accounting stop answer received case FAILED_RECEIVE_RECORD: // Current State: PENDING_L // Event: Failed accounting stop answer received // Action: - // New State: IDLE setState(IDLE); break; } break; } } // Post processing if (oldState != state) { switch (state) { // IDLE =========== case IDLE: { // Current State: IDLE // Event: Records in storage // Action: Send record // New State: PENDING_B try { synchronized (this) { if (sessionData.getBuffer() != null) { session.send(sessionData.getBuffer(), this); setState(PENDING_BUFFERED); } } } catch (Exception e) { logger.debug("can not send buffered message", e); synchronized (this) { Request buffer = sessionData.getBuffer(); if (context != null && buffer != null) { if (!context.failedSendRecord(this, buffer)) { storeToBuffer(null); } } } } } } } } catch (Throwable t) { throw new InternalException(t); } return true; } protected void processInterimIntervalAvp(StateEvent event) throws InternalException { // Avp interval = ((AppEvent) event.getData()).getMessage().getAvps().getAvp(Avp.ACCT_INTERIM_INTERVAL); // if (interval != null) { // // create timer // try { // long v = interval.getUnsigned32(); // if (v != 0) { // // scheduler.schedule( // // new Runnable() { // // public void run() { // // if (context != null) { // // try { // // Request interimRecord = createInterimRecord(); // // context.interimIntervalElapses(interimRecord); // // sendAndStateLock.lock(); // // session.send(interimRecord, ClientRfSessionImpl.this); // // setState(PENDING_INTERIM); // // } // // catch (Exception e) { // // logger.debug("Can not process Interim Interval AVP", e); // // } // // finally { // // sendAndStateLock.unlock(); // // } // // } // // } // // }, // // v, TimeUnit.SECONDS // // ); // cancelInterimTimer(); // this.timerId_interim = startInterimTimer(v); // } // } // catch (AvpDataException e) { // logger.debug("Unable to retrieve Acct-Interim-Interval AVP value", e); // } // } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TIMER_NAME_INTERIM)) { if (context != null) { try { Request interimRecord = createInterimRecord(); context.interimIntervalElapses(this, interimRecord); sendAndStateLock.lock(); session.send(interimRecord, ClientRfSessionImpl.this); setState(PENDING_INTERIM); sessionData.setTsTimerId(null); } catch (Exception e) { logger.debug("Can not process Interim Interval AVP", e); } finally { sendAndStateLock.unlock(); } } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } private void startInterimTimer(long v) { try { sendAndStateLock.lock(); sessionData.setTsTimerId(super.timerFacility.schedule(getSessionId(), TIMER_NAME_INTERIM, v)); return; } finally { sendAndStateLock.unlock(); } } private void cancelInterimTimer() { try { sendAndStateLock.lock(); final Serializable timerId = this.sessionData.getTsTimerId(); if (timerId != null) { super.timerFacility.cancel(timerId); this.sessionData.setTsTimerId(null); } } finally { sendAndStateLock.unlock(); } } @Override @SuppressWarnings("unchecked") public E getState(Class eClass) { return eClass == ClientRfSessionState.class ? (E) this.sessionData.getClientRfSessionState() : null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { if (request.getCommandCode() == RfAccountingRequest.code) { // state should be changed before event listener call try { sendAndStateLock.lock(); handleEvent(new Event(createAccountAnswer(answer))); } catch (Exception e) { logger.debug("Can not process received request", e); } finally { sendAndStateLock.unlock(); } try { listener.doRfAccountingAnswerEvent(this, createAccountRequest(request), createAccountAnswer(answer)); } catch (Exception e) { logger.debug("Unable to deliver message to listener.", e); } } else { try { listener.doOtherEvent(this, createAccountRequest(request), createAccountAnswer(answer)); } catch (Exception e) { logger.debug("Can not process received request", e); } } } @Override public void timeoutExpired(Request request) { try { sendAndStateLock.lock(); handleEvent(new Event(Event.Type.FAILED_RECEIVE_RECORD, createAccountRequest(request))); } catch (Exception e) { logger.debug("Can not handle timeout event", e); } finally { sendAndStateLock.unlock(); } } @Override public Answer processRequest(Request request) { if (request.getCommandCode() == RfAccountingRequest.code) { try { // FIXME Is this wrong? listener.doRfAccountingAnswerEvent(this, createAccountRequest(request), null); } catch (Exception e) { logger.debug("Can not process received request", e); } } else { try { listener.doOtherEvent(this, createAccountRequest(request), null); } catch (Exception e) { logger.debug("Can not process received request", e); } } return null; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } protected Request createInterimRecord() { Request interimRecord = session.createRequest(RfAccountingRequest.code, appId, sessionData.getDestinationRealm(), sessionData.getDestinationHost()); interimRecord.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 3); return interimRecord; } protected Request createSessionTermRequest() { return session.createRequest(Message.SESSION_TERMINATION_REQUEST, appId, sessionData.getDestinationRealm(), sessionData.getDestinationHost()); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } ClientRfSessionImpl other = (ClientRfSessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); //TODO: cancel timer? super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/rf/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.rf; import org.jdiameter.api.Avp; import org.jdiameter.api.ResultCode; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.rf.events.RfAccountingAnswer; import org.jdiameter.api.rf.events.RfAccountingRequest; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib class Event implements StateEvent { enum Type { SEND_EVENT_RECORD, SEND_START_RECORD, SEND_INTERIM_RECORD, SEND_STOP_RECORD, FAILED_SEND_RECORD, RECEIVED_RECORD, FAILED_RECEIVE_RECORD } Type type; AppEvent data; Event(Type type) { this.type = type; } Event(RfAccountingAnswer accountAnswer) throws Exception { int resCode = ResultCode.SUCCESS; try { resCode = accountAnswer.getMessage().getAvps().getAvp(Avp.RESULT_CODE).getInteger32(); } catch (Exception exc) { } type = (resCode == ResultCode.SUCCESS || (resCode / 1000 == 4)) ? Type.RECEIVED_RECORD : Type.FAILED_RECEIVE_RECORD; data = accountAnswer; } Event(RfAccountingRequest accountRequest) throws Exception { data = accountRequest; int type = accountRequest.getAccountingRecordType(); //legal, its int size... switch (type) { case 1: this.type = Type.SEND_EVENT_RECORD; break; case 2: this.type = Type.SEND_START_RECORD; break; case 3: this.type = Type.SEND_INTERIM_RECORD; break; case 4: this.type = Type.SEND_STOP_RECORD; break; default: throw new Exception("Unknown type " + type); } } Event(Type type, RfAccountingRequest accountRequest) throws Exception { this.type = type; this.data = accountRequest; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public void setData(Object o) { data = (AppEvent) o; } @Override public Object getData() { return data; } @Override public int compareTo(Object o) { return 0; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/rf/IClientRfSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.rf; import java.io.Serializable; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.rf.ClientRfSessionState; import org.jdiameter.common.api.app.rf.IRfSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientRfSessionData extends IRfSessionData { void setClientRfSessionState(ClientRfSessionState state); ClientRfSessionState getClientRfSessionState(); void setBuffer(Request event); Request getBuffer(); @Override ApplicationId getApplicationId(); @Override void setApplicationId(ApplicationId appId); Serializable getTsTimerId(); void setTsTimerId(Serializable tid); String getDestinationHost(); void setDestinationHost(String destinationHost); String getDestinationRealm(); void setDestinationRealm(String destinationRealm); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.ro; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.ro.ClientRoSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientRoSessionDataLocalImpl extends AppSessionDataLocalImpl implements IClientRoSessionData { protected boolean isEventBased = true; protected boolean requestTypeSet = false; protected ClientRoSessionState state = ClientRoSessionState.IDLE; protected Serializable txTimerId; //protected JCreditControlRequest txTimerRequest; protected Request txTimerRequest; // Event Based Buffer //protected Message buffer = null; protected Request buffer; protected int gatheredRequestedAction = NON_INITIALIZED; protected int gatheredCCFH = NON_INITIALIZED; protected int gatheredDDFH = NON_INITIALIZED; /** * */ public ClientRoSessionDataLocalImpl() { } @Override public boolean isEventBased() { return isEventBased; } @Override public void setEventBased(boolean isEventBased) { this.isEventBased = isEventBased; } @Override public boolean isRequestTypeSet() { return requestTypeSet; } @Override public void setRequestTypeSet(boolean requestTypeSet) { this.requestTypeSet = requestTypeSet; } @Override public ClientRoSessionState getClientRoSessionState() { return state; } @Override public void setClientRoSessionState(ClientRoSessionState state) { this.state = state; } @Override public Serializable getTxTimerId() { return txTimerId; } @Override public void setTxTimerId(Serializable txTimerId) { this.txTimerId = txTimerId; } @Override public Request getTxTimerRequest() { return txTimerRequest; } @Override public void setTxTimerRequest(Request txTimerRequest) { this.txTimerRequest = txTimerRequest; } @Override public Request getBuffer() { return buffer; } @Override public void setBuffer(Request buffer) { this.buffer = buffer; } @Override public int getGatheredRequestedAction() { return gatheredRequestedAction; } @Override public void setGatheredRequestedAction(int gatheredRequestedAction) { this.gatheredRequestedAction = gatheredRequestedAction; } @Override public int getGatheredCCFH() { return gatheredCCFH; } @Override public void setGatheredCCFH(int gatheredCCFH) { this.gatheredCCFH = gatheredCCFH; } @Override public int getGatheredDDFH() { return gatheredDDFH; } @Override public void setGatheredDDFH(int gatheredDDFH) { this.gatheredDDFH = gatheredDDFH; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.ro; import org.jdiameter.api.*; import org.jdiameter.api.app.*; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.ro.ClientRoSession; import org.jdiameter.api.ro.ClientRoSessionListener; import org.jdiameter.api.ro.events.RoCreditControlAnswer; import org.jdiameter.api.ro.events.RoCreditControlRequest; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.client.impl.app.ro.Event.Type; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.ro.ClientRoSessionState; import org.jdiameter.common.api.app.ro.IClientRoSessionContext; import org.jdiameter.common.api.app.ro.IRoMessageFactory; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.ro.AppRoSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Client Credit-Control Application session implementation * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ClientRoSessionImpl extends AppRoSessionImpl implements ClientRoSession, NetworkReqListener, EventListener { private static final Logger logger = LoggerFactory.getLogger(ClientRoSessionImpl.class); // Session State Handling --------------------------------------------------- protected IClientRoSessionData sessionData; protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IRoMessageFactory factory; protected transient ClientRoSessionListener listener; protected transient IClientRoSessionContext context; protected transient IMessageParser parser; // Tx Timer ----------------------------------------------------------------- protected static final String TX_TIMER_NAME = "Ro_CLIENT_TX_TIMER"; protected static final long TX_TIMER_DEFAULT_VALUE = 30 * 60 * 1000; // miliseconds protected long[] authAppIds = new long[]{4}; // Requested Action + Credit-Control and Direct-Debiting Failure-Handling --- protected static final int CCFH_TERMINATE = 0; protected static final int CCFH_CONTINUE = 1; protected static final int CCFH_RETRY_AND_TERMINATE = 2; private static final int DDFH_TERMINATE_OR_BUFFER = 0; private static final int DDFH_CONTINUE = 1; // CC-Request-Type Values --------------------------------------------------- private static final int DIRECT_DEBITING = 0; private static final int REFUND_ACCOUNT = 1; private static final int CHECK_BALANCE = 2; private static final int PRICE_ENQUIRY = 3; private static final int EVENT_REQUEST = 4; // Error Codes -------------------------------------------------------------- private static final long END_USER_SERVICE_DENIED = 4010; private static final long CREDIT_CONTROL_NOT_APPLICABLE = 4011; private static final long USER_UNKNOWN = 5030; private static final long DIAMETER_UNABLE_TO_DELIVER = 3002L; private static final long DIAMETER_TOO_BUSY = 3004L; private static final long DIAMETER_LOOP_DETECTED = 3005L; protected static final Set temporaryErrorCodes; static { HashSet tmp = new HashSet(); tmp.add(DIAMETER_UNABLE_TO_DELIVER); tmp.add(DIAMETER_TOO_BUSY); tmp.add(DIAMETER_LOOP_DETECTED); temporaryErrorCodes = Collections.unmodifiableSet(tmp); } // Session Based Queue protected ArrayList eventQueue = new ArrayList(); public ClientRoSessionImpl(IClientRoSessionData sessionData, IRoMessageFactory fct, ISessionFactory sf, ClientRoSessionListener lst, IClientRoSessionContext ctx, StateChangeListener stLst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationIds() == null) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } if (sessionData == null) { throw new IllegalArgumentException("SessionData can not be null"); } this.context = ctx; this.sessionData = sessionData; this.authAppIds = fct.getApplicationIds(); this.listener = lst; this.factory = fct; IContainer icontainer = sf.getContainer(); this.parser = icontainer.getAssemblerFacility().getComponentInstance(IMessageParser.class); super.addStateChangeNotification(stLst); } public void setListener(ClientRoSessionListener listener) { this.listener = listener; } protected int getLocalCCFH() { return sessionData.getGatheredCCFH() >= 0 ? sessionData.getGatheredCCFH() : context.getDefaultCCFHValue(); } protected int getLocalDDFH() { return sessionData.getGatheredDDFH() >= 0 ? sessionData.getGatheredDDFH() : context.getDefaultDDFHValue(); } @Override public void sendCreditControlRequest(RoCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { try { extractFHAVPs(request, null); this.handleEvent(new Event(true, request, null)); } catch (AvpDataException e) { throw new InternalException(e); } } @Override public void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { this.handleEvent(new Event(Event.Type.SEND_RAA, null, answer)); } @Override public boolean isStateless() { return false; } public boolean isEventBased() { return sessionData.isEventBased(); } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == ClientRoSessionState.class ? (E) sessionData.getClientRoSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return this.isEventBased() ? handleEventForEventBased(event) : handleEventForSessionBased(event); } protected boolean handleEventForEventBased(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); ClientRoSessionState state = sessionData.getClientRoSessionState(); Event localEvent = (Event) event; Event.Type eventType = (Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case SEND_EVENT_REQUEST: // Current State: IDLE // Event: Client or device requests a one-time service // Action: Send CC event request, start Tx // New State: PENDING_E startTx((RoCreditControlRequest) localEvent.getRequest()); setState(ClientRoSessionState.PENDING_EVENT); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table logger.debug("Failure handling send event request", e); handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_EVENT: switch (eventType) { case RECEIVE_EVENT_ANSWER: AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer(); try { long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_E // Event: Successful CC event answer received // Action: Grant service to end user // New State: IDLE setState(ClientRoSessionState.IDLE, false); } if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType); } deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); } catch (AvpDataException e) { logger.debug("Failure handling received answer event", e); setState(ClientRoSessionState.IDLE, false); } break; case Tx_TIMER_FIRED: handleTxExpires(localEvent.getRequest().getMessage()); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_BUFFERED: switch (eventType) { case RECEIVE_EVENT_ANSWER: // Current State: PENDING_B // Event: Successful CC answer received // Action: Delete request // New State: IDLE setState(ClientRoSessionState.IDLE, false); sessionData.setBuffer(null); deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } dispatch(); return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } protected boolean handleEventForSessionBased(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); ClientRoSessionState state = sessionData.getClientRoSessionState(); Event localEvent = (Event) event; Event.Type eventType = (Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case SEND_INITIAL_REQUEST: // Current State: IDLE // Event: Client or device requests access/service // Action: Send CC initial request, start Tx // New State: PENDING_I startTx((RoCreditControlRequest) localEvent.getRequest()); setState(ClientRoSessionState.PENDING_INITIAL); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_INITIAL: AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVED_INITIAL_ANSWER: long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_I // Event: Successful CC initial answer received // Action: Stop Tx // New State: OPEN stopTx(); setState(ClientRoSessionState.OPEN); } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType); } deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: handleTxExpires(localEvent.getRequest().getMessage()); break; case SEND_UPDATE_REQUEST: case SEND_TERMINATE_REQUEST: // Current State: PENDING_I // Event: User service terminated // Action: Queue termination event // New State: PENDING_I // Current State: PENDING_I // Event: Change in rating condition // Action: Queue changed rating condition event // New State: PENDING_I eventQueue.add(localEvent); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case OPEN: switch (eventType) { case SEND_UPDATE_REQUEST: // Current State: OPEN // Event: Granted unit elapses and no final unit indication received // Action: Send CC update request, start Tx // New State: PENDING_U // Current State: OPEN // Event: Change in rating condition in queue // Action: Send CC update request, start Tx // New State: PENDING_U // Current State: OPEN // Event: Change in rating condition or Validity-Time elapses // Action: Send CC update request, start Tx // New State: PENDING_U // Current State: OPEN // Event: RAR received // Action: Send RAA followed by CC update request, start Tx // New State: PENDING_U startTx((RoCreditControlRequest) localEvent.getRequest()); setState(ClientRoSessionState.PENDING_UPDATE); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case SEND_TERMINATE_REQUEST: // Current State: OPEN // Event: Granted unit elapses and final unit action equal to TERMINATE received // Action: Terminate end user�s service, send CC termination request // New State: PENDING_T // Current State: OPEN // Event: Service terminated in queue // Action: Send CC termination request // New State: PENDING_T // Current State: OPEN // Event: User service terminated // Action: Send CC termination request // New State: PENDING_T setState(ClientRoSessionState.PENDING_TERMINATION); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case RECEIVED_RAR: deliverRAR((ReAuthRequest) localEvent.getRequest()); break; case SEND_RAA: try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_UPDATE: answer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVED_UPDATE_ANSWER: long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_U // Event: Successful CC update answer received // Action: Stop Tx // New State: OPEN stopTx(); setState(ClientRoSessionState.OPEN); } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType); } deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); break; case Tx_TIMER_FIRED: handleTxExpires(localEvent.getRequest().getMessage()); break; case SEND_UPDATE_REQUEST: case SEND_TERMINATE_REQUEST: // Current State: PENDING_U // Event: User service terminated // Action: Queue termination event // New State: PENDING_U // Current State: PENDING_U // Event: Change in rating condition // Action: Queue changed rating condition event // New State: PENDING_U eventQueue.add(localEvent); break; case RECEIVED_RAR: deliverRAR((ReAuthRequest) localEvent.getRequest()); break; case SEND_RAA: // Current State: PENDING_U // Event: RAR received // Action: Send RAA // New State: PENDING_U try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; } break; case PENDING_TERMINATION: switch (eventType) { case SEND_UPDATE_REQUEST: try { // Current State: PENDING_T // Event: Change in rating condition // Action: - // New State: PENDING_T dispatchEvent(localEvent.getRequest()); // No transition } catch (Exception e) { // This handles failure to send in PendingI state in FSM table // handleSendFailure(e, eventType); } break; case RECEIVED_TERMINATED_ANSWER: // Current State: PENDING_T // Event: Successful CC termination answer received // Action: - // New State: IDLE // Current State: PENDING_T // Event: Failure to send, temporary error, or failed answer // Action: - // New State: IDLE //FIXME: Alex broke this, setting back "true" ? //setState(ClientRoSessionState.IDLE, false); deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer()); setState(ClientRoSessionState.IDLE, true); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } break; default: // any other state is bad setState(ClientRoSessionState.IDLE, true); } dispatch(); return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery ad = new AnswerDelivery(); ad.session = this; ad.request = request; ad.answer = answer; super.scheduler.execute(ad); } @Override public void timeoutExpired(Request request) { if (request.getCommandCode() == RoCreditControlAnswer.code) { try { sendAndStateLock.lock(); handleSendFailure(null, null, request); } catch (Exception e) { logger.debug("Failure processing timeout message for request", e); } finally { sendAndStateLock.unlock(); } } } protected void startTx(RoCreditControlRequest request) { long txTimerValue = context.getDefaultTxTimerValue(); if (txTimerValue < 0) { txTimerValue = TX_TIMER_DEFAULT_VALUE; } stopTx(); logger.debug("Scheduling TX Timer {}", txTimerValue); //this.txFuture = scheduler.schedule(new TxTimerTask(this, request), txTimerValue, TimeUnit.SECONDS); try { sessionData.setTxTimerRequest((Request) request.getMessage()); sessionData.setTxTimerId( this.timerFacility.schedule(this.sessionData.getSessionId(), TX_TIMER_NAME, TX_TIMER_DEFAULT_VALUE)); } catch (Exception e) { throw new IllegalArgumentException("Failed to store request.", e); } } protected void stopTx() { Serializable txTimerId = this.sessionData.getTxTimerId(); if (txTimerId != null) { timerFacility.cancel(txTimerId); sessionData.setTxTimerId(null); sessionData.setTxTimerRequest(null); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TX_TIMER_NAME)) { new TxTimerTask(this, sessionData.getTxTimerRequest()).run(); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } protected void setState(ClientRoSessionState newState) { setState(newState, true); } @SuppressWarnings("unchecked") protected void setState(ClientRoSessionState newState, boolean release) { try { IAppSessionState state = sessionData.getClientRoSessionState(); IAppSessionState oldState = state; sessionData.setClientRoSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == ClientRoSessionState.IDLE) { if (release) { this.release(); } stopTx(); } } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug( "Failure switching to state " + sessionData.getClientRoSessionState() + " (release=" + release + ")", e); } } } @Override public void release() { if (isValid()) { try { this.sendAndStateLock.lock(); this.stopTx(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { this.sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void handleSendFailure(Exception e, Event.Type eventType, Message request) throws Exception { logger.debug("Failed to send message, type: {} message: {}, failure: {}", new Object[]{eventType, request, e != null ? e.getLocalizedMessage() : ""}); try { ClientRoSessionState state = sessionData.getClientRoSessionState(); // Event Based ---------------------------------------------------------- if (isEventBased()) { int gatheredRequestedAction = sessionData.getGatheredRequestedAction(); switch (state) { case PENDING_EVENT: if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE setState(ClientRoSessionState.IDLE); context.indicateServiceError(this); } else if (gatheredRequestedAction == DIRECT_DEBITING) { switch (getLocalDDFH()) { case DDFH_TERMINATE_OR_BUFFER: // Current State: PENDING_E // Event: Failure to send; request action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER // Action: Store request with T-flag // New State: IDLE request.setReTransmitted(true); sessionData.setBuffer((Request) request); setState(ClientRoSessionState.IDLE, false); break; case DDFH_CONTINUE: // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnDeliverFailure(this, request); break; default: logger.warn("Invalid Direct-Debiting-Failure-Handling AVP value {}", getLocalDDFH()); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag // New State: IDLE setState(ClientRoSessionState.IDLE, false); request.setReTransmitted(true); sessionData.setBuffer((Request) request); } else { logger.warn("Invalid Requested-Action AVP value {}", gatheredRequestedAction); } break; case PENDING_BUFFERED: // Current State: PENDING_B // Event: Failure to send or temporary error // Action: - // New State: IDLE setState(ClientRoSessionState.IDLE, false); sessionData.setBuffer(null);// FIXME: Action does not mention, but ... break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); break; } } // Session Based -------------------------------------------------------- else { switch (getLocalCCFH()) { case CCFH_CONTINUE: // Current State: PENDING_I // Event: Failure to send, or temporary error and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE // Current State: PENDING_U // Event: Failure to send, or temporary error and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE setState(ClientRoSessionState.IDLE, false); this.context.grantAccessOnDeliverFailure(this, request); break; default: // Current State: PENDING_I // Event: Failure to send, or temporary error and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE // Action: Terminate end user�s service // New State: IDLE // Current State: PENDING_U // Event: Failure to send, or temporary error and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE // Action: Terminate end user�s service // New State: IDLE this.context.denyAccessOnDeliverFailure(this, request); setState(ClientRoSessionState.IDLE, true); break; } } } finally { dispatch(); } } protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControlRequest request, Event.Type eventType) { try { // Event Based ---------------------------------------------------------- long resultCode = event.getResultCodeAvp().getUnsigned32(); ClientRoSessionState state = sessionData.getClientRoSessionState(); Serializable txTimerId = sessionData.getTxTimerId(); if (isEventBased()) { int gatheredRequestedAction = sessionData.getGatheredRequestedAction(); switch (state) { case PENDING_EVENT: if (resultCode == END_USER_SERVICE_DENIED || resultCode == USER_UNKNOWN) { if (txTimerId != null) { // Current State: PENDING_E // Event: CC event answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN and Tx running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) { // Current State: PENDING_E // Event: Failed answer or answer received w/ result code END_USER_SERVICE DENIED or USER_UNKNOWN; requested action DIRECT_DEBITING; Tx expired // Action: - // New State: IDLE setState(ClientRoSessionState.IDLE); } } else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) { // Current State: PENDING_E // Event: CC event answer received with result code CREDIT_CONTROL_NOT_APPLICABLE; requested action DIRECT_DEBITING // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } else if (temporaryErrorCodes.contains(resultCode)) { if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE context.indicateServiceError(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Temporary error, and requested action REFUND_ACCOUNT // Action: Store request // New State: IDLE sessionData.setBuffer((Request) request); setState(ClientRoSessionState.IDLE, false); } else { logger.warn( "Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } } else { // Failure if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE context.indicateServiceError(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (getLocalDDFH() == DDFH_CONTINUE) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) { // Current State: PENDING_E // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failed CC event answer received; requested action REFUND_ACCOUNT // Action: Indicate service error and delete request // New State: IDLE sessionData.setBuffer(null); context.indicateServiceError(this); deliverRoAnswer(request, event); setState(ClientRoSessionState.IDLE); } else { logger.warn( "Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId}); } } break; case PENDING_BUFFERED: // Current State: PENDING_B // Event: Failed CC answer received // Action: Delete request // New State: IDLE sessionData.setBuffer(null); setState(ClientRoSessionState.IDLE, false); break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); } } // Session Based -------------------------------------------------------- else { switch (state) { case PENDING_INITIAL: if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE) { // Current State: PENDING_I // Event: CC initial answer received with result code equal to CREDIT_CONTROL_NOT_APPLICABLE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); } else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) { // Current State: PENDING_I // Event: CC initial answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: // Current State: PENDING_I // Event: Failed CC initial answer received and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); break; case CCFH_TERMINATE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_I // Event: Failed CC initial answer received and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); break; default: logger.warn("Invalid value for CCFH: {}", getLocalCCFH()); break; } } break; case PENDING_UPDATE: if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE) { // Current State: PENDING_U // Event: CC update answer received with result code equal to CREDIT_CONTROL_NOT_APPLICABLE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); } else if (resultCode == END_USER_SERVICE_DENIED) { // Current State: PENDING_U // Event: CC update answer received with result code END_USER_SERVICE_DENIED // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); } else { // Temporary errors and others switch (getLocalCCFH()) { case CCFH_CONTINUE: // Current State: PENDING_U // Event: Failed CC update answer received and CCFH equal to CONTINUE // Action: Grant service to end user // New State: IDLE context.grantAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); break; case CCFH_TERMINATE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_U // Event: Failed CC update answer received and CCFH equal to CONTINUE or to RETRY_AND_CONTINUE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnFailureMessage(this); setState(ClientRoSessionState.IDLE, false); break; default: logger.warn("Invalid value for CCFH: " + getLocalCCFH()); break; } } break; default: logger.warn("Wrong event type ({}) on state {}", eventType, state); } } } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug( "Failure handling failure message for Event " + event + " (" + eventType + ") and Request " + request, e); } } } protected void handleTxExpires(Message message) { // Event Based ---------------------------------------------------------- ClientRoSessionState state = sessionData.getClientRoSessionState(); if (isEventBased()) { int gatheredRequestedAction = sessionData.getGatheredRequestedAction(); if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) { // Current State: PENDING_E // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY // Action: Indicate service error // New State: IDLE context.indicateServiceError(this); setState(ClientRoSessionState.IDLE); } else if (gatheredRequestedAction == DIRECT_DEBITING) { if (sessionData.getGatheredDDFH() == DDFH_TERMINATE_OR_BUFFER) { // Current State: PENDING_E // Event: Temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER; Tx expired // Action: Store request // New State: IDLE sessionData.setBuffer((Request) message); setState(ClientRoSessionState.IDLE, false); } else { // Current State: PENDING_E // Event: Tx expired; requested action DIRECT_DEBITING // Action: Grant service to end user // New State: PENDING_E context.grantAccessOnTxExpire(this); setState(ClientRoSessionState.PENDING_EVENT); } } else if (gatheredRequestedAction == REFUND_ACCOUNT) { // Current State: PENDING_E // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT // Action: Store request with T-flag // New State: IDLE message.setReTransmitted(true); sessionData.setBuffer((Request) message); setState(ClientRoSessionState.IDLE, false); } } // Session Based -------------------------------------------------------- else { switch (state) { case PENDING_INITIAL: switch (getLocalCCFH()) { case CCFH_CONTINUE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_I // Event: Tx expired and CCFH equal to CONTINUE or to RETRY_AND_TERMINATE // Action: Grant service to end user // New State: PENDING_I context.grantAccessOnTxExpire(this); break; case CCFH_TERMINATE: // Current State: PENDING_I // Event: Tx expired and CCFH equal to TERMINATE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnTxExpire(this); setState(ClientRoSessionState.IDLE, true); break; default: logger.warn("Invalid value for CCFH: " + getLocalCCFH()); break; } break; case PENDING_UPDATE: switch (getLocalCCFH()) { case CCFH_CONTINUE: case CCFH_RETRY_AND_TERMINATE: // Current State: PENDING_U // Event: Tx expired and CCFH equal to CONTINUE or to RETRY_AND_TERMINATE // Action: Grant service to end user // New State: PENDING_U context.grantAccessOnTxExpire(this); break; case CCFH_TERMINATE: // Current State: PENDING_U // Event: Tx expired and CCFH equal to TERMINATE // Action: Terminate end user�s service // New State: IDLE context.denyAccessOnTxExpire(this); setState(ClientRoSessionState.IDLE, true); break; default: logger.error("Bad value of CCFH: " + getLocalCCFH()); break; } break; default: logger.error("Unknown state (" + sessionData.getClientRoSessionState() + ") on txExpire"); break; } } } /** * This makes checks on queue, moves it to proper state if event there is present on Open state ;] */ protected void dispatch() { // Event Based ---------------------------------------------------------- if (isEventBased()) { // Current State: IDLE // Event: Request in storage // Action: Send stored request // New State: PENDING_B Request buffer = sessionData.getBuffer(); if (buffer != null) { setState(ClientRoSessionState.PENDING_BUFFERED); try { dispatchEvent(new AppRequestEventImpl(buffer)); } catch (Exception e) { try { handleSendFailure(e, Event.Type.SEND_EVENT_REQUEST, buffer); } catch (Exception e1) { logger.error("Failure handling buffer send failure", e1); } } } } // Session Based -------------------------------------------------------- else { if (sessionData.getClientRoSessionState() == ClientRoSessionState.OPEN && eventQueue.size() > 0) { try { this.handleEvent(eventQueue.remove(0)); } catch (Exception e) { logger.error("Failure handling queued event", e); } } } } protected void deliverRoAnswer(RoCreditControlRequest request, RoCreditControlAnswer answer) { try { if (isValid()) { listener.doCreditControlAnswer(this, request, answer); } } catch (Exception e) { logger.warn("Failure delivering Ro Answer", e); } } protected void extractFHAVPs(RoCreditControlRequest request, RoCreditControlAnswer answer) throws AvpDataException { if (answer != null) { try { if (answer.isCreditControlFailureHandlingAVPPresent()) { sessionData.setGatheredCCFH(answer.getCredidControlFailureHandlingAVPValue()); } } catch (Exception e) { logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e); } try { if (answer.isDirectDebitingFailureHandlingAVPPresent()) { sessionData.setGatheredDDFH(answer.getDirectDebitingFailureHandlingAVPValue()); } } catch (Exception e) { logger.debug("Failure trying to obtain Direct-Debit-Failure-Handling AVP value", e); } if (!sessionData.isRequestTypeSet()) { sessionData.setRequestTypeSet(true); // No need to check if it exists.. it must, if not fail with exception sessionData.setEventBased(answer.getRequestTypeAVPValue() == EVENT_REQUEST); } } else if (request != null) { try { if (request.isRequestedActionAVPPresent()) { sessionData.setGatheredRequestedAction(request.getRequestedActionAVPValue()); } } catch (Exception e) { logger.debug("Failure trying to obtain Request-Action AVP value", e); } if (!sessionData.isRequestTypeSet()) { sessionData.setRequestTypeSet(true); // No need to check if it exists.. it must, if not fail with exception sessionData.setEventBased(request.getRequestTypeAVPValue() == EVENT_REQUEST); } } } protected void deliverRAR(ReAuthRequest request) { try { listener.doReAuthRequest(this, request); } catch (Exception e) { logger.debug("Failure delivering RAR", e); } } protected void dispatchEvent(AppEvent event) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { session.send(event.getMessage(), this); } protected boolean isProvisional(long resultCode) { return resultCode >= 1000 && resultCode < 2000; } protected boolean isSuccess(long resultCode) { return resultCode >= 2000 && resultCode < 3000; } protected boolean isFailure(long code) { return (!isProvisional(code) && !isSuccess(code) && ((code >= 3000 && code < 6000)) && !temporaryErrorCodes.contains(code)); } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } private class TxTimerTask implements Runnable { private ClientRoSession session = null; private Request request = null; private TxTimerTask(ClientRoSession session, Request request) { super(); this.session = session; this.request = request; } @Override public void run() { try { sendAndStateLock.lock(); logger.debug("Fired TX Timer"); sessionData.setTxTimerId(null); sessionData.setTxTimerRequest(null); try { context.txTimerExpired(session); } catch (Exception e) { logger.debug("Failure handling TX Timer Expired", e); } RoCreditControlRequest req = factory.createCreditControlRequest(request); handleEvent(new Event(Event.Type.Tx_TIMER_FIRED, req, null)); } catch (InternalException e) { logger.error("Internal Exception", e); } catch (OverloadException e) { logger.error("Overload Exception", e); } catch (Exception e) { logger.error("Exception", e); } finally { sendAndStateLock.unlock(); } } } private Message messageFromBuffer(ByteBuffer request) throws InternalException { if (request != null) { Message m; try { m = parser.createMessage(request); return m; } catch (AvpDataException e) { throw new InternalException("Failed to decode message.", e); } } return null; } private ByteBuffer messageToBuffer(IMessage msg) throws InternalException { try { return parser.encodeMessage(msg); } catch (ParseException e) { throw new InternalException("Failed to encode message.", e); } } private class RequestDelivery implements Runnable { ClientRoSession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case ReAuthAnswer.code: handleEvent(new Event(Event.Type.RECEIVED_RAR, factory.createReAuthRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failure processing request", e); } } } private class AnswerDelivery implements Runnable { ClientRoSession session; Answer answer; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case RoCreditControlAnswer.code: RoCreditControlRequest _request = factory.createCreditControlRequest(request); RoCreditControlAnswer _answer = factory.createCreditControlAnswer(answer); extractFHAVPs(null, _answer); handleEvent(new Event(false, _request, _answer)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failure processing success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.ro; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.ro.events.RoCreditControlAnswer; import org.jdiameter.api.ro.events.RoCreditControlRequest; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { public enum Type { SEND_INITIAL_REQUEST, RECEIVED_INITIAL_ANSWER, SEND_UPDATE_REQUEST, RECEIVED_UPDATE_ANSWER, SEND_TERMINATE_REQUEST, RECEIVED_TERMINATED_ANSWER, RECEIVED_RAR, SEND_RAA, Tx_TIMER_FIRED, SEND_EVENT_REQUEST, RECEIVE_EVENT_ANSWER; } Type type; AppRequestEvent request; AppAnswerEvent answer; Event(Type type) { this.type = type; } Event(Type type, AppRequestEvent request, AppAnswerEvent answer) { this.type = type; this.answer = answer; this.request = request; } Event(boolean isRequest, RoCreditControlRequest request, RoCreditControlAnswer answer) throws AvpDataException { this.answer = answer; this.request = request; if (isRequest) { switch (request.getRequestTypeAVPValue()) { case 1: type = Type.SEND_INITIAL_REQUEST; break; case 2: type = Type.SEND_UPDATE_REQUEST; break; case 3: type = Type.SEND_TERMINATE_REQUEST; break; case 4: type = Type.SEND_EVENT_REQUEST; break; default: throw new RuntimeException("Wrong CC-Request-Type value: " + request.getRequestTypeAVPValue()); } } else { switch (answer.getRequestTypeAVPValue()) { case 1: type = Type.RECEIVED_INITIAL_ANSWER; break; case 2: type = Type.RECEIVED_UPDATE_ANSWER; break; case 3: type = Type.RECEIVED_TERMINATED_ANSWER; break; case 4: type = Type.RECEIVE_EVENT_ANSWER; break; default: throw new RuntimeException("Wrong CC-Request-Type value: " + answer.getRequestTypeAVPValue()); } } } @Override public Enum getType() { return type; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { // FIXME: What should we do here?! Is it request or answer? } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public E encodeType(Class eClass) { return eClass == Event.Type.class ? (E) type : null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/IClientRoSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.ro; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.ro.ClientRoSessionState; import org.jdiameter.common.api.app.ro.IRoSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientRoSessionData extends IRoSessionData { boolean isEventBased(); void setEventBased(boolean b); boolean isRequestTypeSet(); void setRequestTypeSet(boolean b); ClientRoSessionState getClientRoSessionState(); void setClientRoSessionState(ClientRoSessionState state); Serializable getTxTimerId(); void setTxTimerId(Serializable txTimerId); Request getTxTimerRequest(); void setTxTimerRequest(Request txTimerRequest); Request getBuffer(); void setBuffer(Request buffer); int getGatheredRequestedAction(); void setGatheredRequestedAction(int gatheredRequestedAction); int getGatheredCCFH(); void setGatheredCCFH(int gatheredCCFH); int getGatheredDDFH(); void setGatheredDDFH(int gatheredDDFH); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/rx/ClientRxSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.rx; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.rx.ClientRxSessionState; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ClientRxSessionDataLocalImpl extends AppSessionDataLocalImpl implements IClientRxSessionData { protected boolean isEventBased = true; protected boolean requestTypeSet = false; protected ClientRxSessionState state = ClientRxSessionState.IDLE; /** * */ public ClientRxSessionDataLocalImpl() { } @Override public boolean isEventBased() { return isEventBased; } @Override public void setEventBased(boolean isEventBased) { this.isEventBased = isEventBased; } @Override public boolean isRequestTypeSet() { return requestTypeSet; } @Override public void setRequestTypeSet(boolean requestTypeSet) { this.requestTypeSet = requestTypeSet; } @Override public ClientRxSessionState getClientRxSessionState() { return state; } @Override public void setClientRxSessionState(ClientRxSessionState state) { this.state = state; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/rx/ClientRxSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.rx; import org.jdiameter.api.EventListener; import org.jdiameter.api.*; import org.jdiameter.api.app.*; import org.jdiameter.api.rx.ClientRxSession; import org.jdiameter.api.rx.ClientRxSessionListener; import org.jdiameter.api.rx.events.*; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.client.impl.app.rx.Event.Type; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.rx.ClientRxSessionState; import org.jdiameter.common.api.app.rx.IClientRxSessionContext; import org.jdiameter.common.api.app.rx.IRxMessageFactory; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.rx.AppRxSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; import java.util.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 3GPP IMS Rx Reference Point Client Session implementation * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ClientRxSessionImpl extends AppRxSessionImpl implements ClientRxSession, NetworkReqListener, EventListener { private static final Logger logger = LoggerFactory.getLogger(ClientRxSessionImpl.class); // Session State Handling --------------------------------------------------- //protected boolean isEventBased = true; //protected boolean requestTypeSet = false; //protected ClientRxSessionState state = ClientRxSessionState.IDLE; protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IRxMessageFactory factory; protected transient ClientRxSessionListener listener; protected transient IClientRxSessionContext context; protected transient IMessageParser parser; protected IClientRxSessionData sessionData; // protected String originHost, originRealm; protected long[] authAppIds = new long[]{4}; // Requested Action + Credit-Control and Direct-Debiting Failure-Handling --- static final int NON_INITIALIZED = -300; // Session State Handling --------------------------------------------------- protected boolean isEventBased = false; //protected boolean requestTypeSet = false; //protected ClientRxSessionState state = ClientRxSessionState.IDLE; protected byte[] buffer; protected String originHost, originRealm; // Error Codes -------------------------------------------------------------- private static final long INVALID_SERVICE_INFORMATION = 5061L; private static final long FILTER_RESTRICTIONS = 5062L; private static final long REQUESTED_SERVICE_NOT_AUTHORIZED = 5063L; private static final long DUPLICATED_AF_SESSION = 5064L; private static final long IP_CAN_SESSION_NOT_AVAILABLE = 5065L; private static final long UNAUTHORIZED_NON_EMERGENCY_SESSION = 5066L; private static final long UNAUTHORIZED_SPONSORED_DATA_CONNECTIVITY = 5067L; private static final long DIAMETER_UNABLE_TO_DELIVER = 3002L; private static final long DIAMETER_TOO_BUSY = 3004L; private static final long DIAMETER_LOOP_DETECTED = 3005L; protected static final Set temporaryErrorCodes; static { HashSet tmp = new HashSet(); tmp.add(DIAMETER_UNABLE_TO_DELIVER); tmp.add(DIAMETER_TOO_BUSY); tmp.add(DIAMETER_LOOP_DETECTED); temporaryErrorCodes = Collections.unmodifiableSet(tmp); } // Session Based Queue protected ArrayList eventQueue = new ArrayList(); public ClientRxSessionImpl(IClientRxSessionData sessionData, IRxMessageFactory fct, ISessionFactory sf, ClientRxSessionListener lst, IClientRxSessionContext ctx, StateChangeListener stLst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationIds() == null) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.context = ctx; this.authAppIds = fct.getApplicationIds(); this.listener = lst; this.factory = fct; IContainer icontainer = sf.getContainer(); this.parser = icontainer.getAssemblerFacility().getComponentInstance(IMessageParser.class); this.sessionData = sessionData; super.addStateChangeNotification(stLst); } public void setListener(ClientRxSessionListener listener) { this.listener = listener; } @Override public void sendAARequest(RxAARequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { try { this.handleEvent(new Event(true, request, null)); } catch (AvpDataException e) { throw new InternalException(e); } } @Override public void sendSessionTermRequest(RxSessionTermRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { try { this.handleEvent(new Event(true, request, null)); } catch (AvpDataException e) { throw new InternalException(e); } } @Override public void sendReAuthAnswer(RxReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { this.handleEvent(new Event(Event.Type.SEND_RAA, null, answer)); } @Override public void sendAbortSessionAnswer(RxAbortSessionAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { this.handleEvent(new Event(Event.Type.SEND_ASA, null, answer)); } @Override public boolean isStateless() { return false; } public boolean isEventBased() { return this.isEventBased; } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == ClientRxSessionState.class ? (E) sessionData.getClientRxSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return this.isEventBased() ? handleEventForEventBased(event) : handleEventForSessionBased(event); } protected boolean handleEventForEventBased(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); final ClientRxSessionState state = this.sessionData.getClientRxSessionState(); Event localEvent = (Event) event; Event.Type eventType = (Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case SEND_EVENT_REQUEST: // Current State: IDLE // Event: Client or device requests a one-time service // Action: Send AA event request // New State: PENDING_E setState(ClientRxSessionState.PENDING_EVENT); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table logger.debug("Failure handling send event request", e); handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Event Based Handling - Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_EVENT: switch (eventType) { case RECEIVE_EVENT_ANSWER: AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer(); try { long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_E // Event: Successful AA event answer received // Action: Grant service to end user // New State: IDLE setState(ClientRxSessionState.IDLE, false); } if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage(answer, (AppRequestEvent) localEvent.getRequest(), eventType); } deliverRxAAAnswer((RxAARequest) localEvent.getRequest(), (RxAAAnswer) localEvent.getAnswer()); } catch (AvpDataException e) { logger.debug("Failure handling received answer event", e); setState(ClientRxSessionState.IDLE, false); } break; default: logger.warn("Event Based Handling - Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_BUFFERED: switch (eventType) { case RECEIVE_EVENT_ANSWER: // Current State: PENDING_B // Event: Successful CC answer received // Action: Delete request // New State: IDLE setState(ClientRxSessionState.IDLE, false); //this.sessionData.setBuffer(null); buffer = null; deliverRxAAAnswer((RxAARequest) localEvent.getRequest(), (RxAAAnswer) localEvent.getAnswer()); break; default: logger.warn("Event Based Handling - Wrong event type ({}) on state {}", eventType, state); break; } break; default: logger.warn("Event Based Handling - Wrong event type ({}) on state {}", eventType, state); break; } dispatch(); return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } protected boolean handleEventForSessionBased(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); final ClientRxSessionState state = this.sessionData.getClientRxSessionState(); Event localEvent = (Event) event; Event.Type eventType = (Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case SEND_AAR: // Current State: IDLE // Event: Client or device requests access/service // Action: Send AAR // New State: PENDING_AAR setState(ClientRxSessionState.PENDING_AAR); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Session Based Handling - Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_AAR: AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVE_AAA: long resultCode = answer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_AAR // Event: Successful AA answer received // New State: OPEN setState(ClientRxSessionState.OPEN); } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage(answer, (AppRequestEvent) localEvent.getRequest(), eventType); } deliverRxAAAnswer((RxAARequest) localEvent.getRequest(), (RxAAAnswer) localEvent.getAnswer()); break; case SEND_AAR: case SEND_STR: // Current State: PENDING_AAR // Event: User service terminated // Action: Queue termination event // New State: PENDING_AAR // Current State: PENDING_AAR // Event: Change in request // Action: Queue changed rating condition event // New State: PENDING_AAR eventQueue.add(localEvent); break; case RECEIVE_RAR: deliverReAuthRequest((RxReAuthRequest) localEvent.getRequest()); break; case SEND_RAA: // Current State: PENDING_U // Event: RAR received // Action: Send RAA // New State: PENDING_U try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case RECEIVE_ASR: deliverAbortSessionRequest((RxAbortSessionRequest) localEvent.getRequest()); break; case SEND_ASA: try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Session Based Handling - Wrong event type ({}) on state {}", eventType, state); break; } break; case PENDING_STR: AppAnswerEvent stanswer = (AppAnswerEvent) localEvent.getAnswer(); switch (eventType) { case RECEIVE_STA: long resultCode = stanswer.getResultCodeAvp().getUnsigned32(); if (isSuccess(resultCode)) { // Current State: PENDING_STR // Event: Successful ST answer received // New State: IDLE setState(ClientRxSessionState.IDLE, false); } else if (isProvisional(resultCode) || isFailure(resultCode)) { handleFailureMessage(stanswer, (AppRequestEvent) localEvent.getRequest(), eventType); } deliverRxSessionTermAnswer((RxSessionTermRequest) localEvent.getRequest(), (RxSessionTermAnswer) localEvent.getAnswer()); break; case SEND_AAR: try { // Current State: PENDING_STR // Event: Change in AA request // Action: - // New State: PENDING_STR dispatchEvent(localEvent.getRequest()); // No transition } catch (Exception e) { // This handles failure to send in PendingI state in FSM table // handleSendFailure(e, eventType); } break; // case RECEIVE_STA: // // Current State: PENDING_T // // Event: Successful CC termination answer received // // Action: - // // New State: IDLE // // // Current State: PENDING_T // // Event: Failure to send, temporary error, or failed answer // // Action: - // // New State: IDLE // // //FIXME: Alex broke this, setting back "true" ? // setState(ClientRxSessionState.IDLE, false); // //setState(ClientRxSessionState.IDLE, true); // deliverRxSessionTermAnswer((RxSessionTermRequest) localEvent.getRequest(), (RxSessionTermAnswer) localEvent.getAnswer()); // //setState(ClientRxSessionState.IDLE, true); // break; default: logger.warn("Session Based Handling - Wrong event type ({}) on state {}", eventType, state); break; } break; case OPEN: switch (eventType) { case SEND_AAR: // Current State: OPEN // Event: Updated AAR send by AF // Action: Send AAR update request // New State: PENDING_AAR setState(ClientRxSessionState.PENDING_AAR); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { // This handles failure to send in PendingI state in FSM table handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case SEND_STR: // Current State: OPEN // Event: Session Termination event request received to be sent // Action: Terminate end user's service, send STR termination request // New State: PENDING STR setState(ClientRxSessionState.PENDING_STR); try { dispatchEvent(localEvent.getRequest()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case RECEIVE_RAR: deliverReAuthRequest((RxReAuthRequest) localEvent.getRequest()); break; case SEND_RAA: try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; case RECEIVE_ASR: deliverAbortSessionRequest((RxAbortSessionRequest) localEvent.getRequest()); break; case SEND_ASA: try { dispatchEvent(localEvent.getAnswer()); } catch (Exception e) { handleSendFailure(e, eventType, localEvent.getRequest().getMessage()); } break; default: logger.warn("Session Based Handling - Wrong event type ({}) on state {}", eventType, state); break; } break; default: // any other state is bad setState(ClientRxSessionState.IDLE, true); break; } dispatch(); return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery ad = new AnswerDelivery(); ad.session = this; ad.request = request; ad.answer = answer; super.scheduler.execute(ad); } @Override public void timeoutExpired(Request request) { // if (request.getCommandCode() == RxAAAnswer.code) { // try { // handleSendFailure(null, null, request); // } // catch (Exception e) { // logger.debug("Failure processing timeout message for request", e); // } // } } protected void setState(ClientRxSessionState newState) { setState(newState, true); } @SuppressWarnings("unchecked") protected void setState(ClientRxSessionState newState, boolean release) { try { IAppSessionState oldState = this.sessionData.getClientRxSessionState(); this.sessionData.setClientRxSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == ClientRxSessionState.IDLE) { if (release) { this.release(); } } } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure switching to state " + this.sessionData.getClientRxSessionState() + " (release=" + release + ")", e); } } } @Override public void release() { if (isValid()) { try { this.sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void handleSendFailure(Exception e, Event.Type eventType, Message request) throws Exception { logger.debug("Failed to send message, type: {} message: {}, failure: {}", new Object[]{eventType, request, e != null ? e.getLocalizedMessage() : ""}); //try { // setState(ClientRxSessionState.IDLE); //} //finally { // dispatch(); //} } protected void handleFailureMessage(final AppAnswerEvent event, final AppRequestEvent request, final Event.Type eventType) { try { setState(ClientRxSessionState.IDLE); } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug( "Failure handling failure message for Event " + event + " (" + eventType + ") and Request " + request, e); } } } /** * This makes checks on queue, moves it to proper state if event there is present on Open state ;] */ protected void dispatch() { // Event Based ---------------------------------------------------------- if (isEventBased()) { // Current State: IDLE // Event: Request in storage // Action: Send stored request // New State: PENDING_B if (buffer != null) { setState(ClientRxSessionState.PENDING_BUFFERED); try { dispatchEvent(new AppRequestEventImpl(messageFromBuffer(ByteBuffer.wrap(buffer)))); } catch (Exception e) { try { handleSendFailure(e, Event.Type.SEND_EVENT_REQUEST, messageFromBuffer(ByteBuffer.wrap(buffer))); } catch (Exception e1) { logger.error("Failure handling buffer send failure", e1); } } } } // Session Based -------------------------------------------------------- else { if (sessionData.getClientRxSessionState() == ClientRxSessionState.OPEN && eventQueue.size() > 0) { try { this.handleEvent(eventQueue.remove(0)); } catch (Exception e) { logger.error("Failure handling queued event", e); } } } } protected void deliverRxAAAnswer(RxAARequest request, RxAAAnswer answer) { try { listener.doAAAnswer(this, request, answer); } catch (Exception e) { logger.warn("Failure delivering AAA", e); } } protected void deliverRxSessionTermAnswer(RxSessionTermRequest request, RxSessionTermAnswer answer) { try { listener.doSessionTermAnswer(this, request, answer); } catch (Exception e) { logger.warn("Failure delivering STA", e); } } protected void deliverReAuthRequest(RxReAuthRequest request) { try { listener.doReAuthRequest(this, request); } catch (Exception e) { logger.debug("Failure delivering RAR", e); } } protected void deliverAbortSessionRequest(RxAbortSessionRequest request) { try { listener.doAbortSessionRequest(this, request); } catch (Exception e) { logger.debug("Failure delivering RAR", e); } } protected void dispatchEvent(AppEvent event) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { session.send(event.getMessage(), this); } protected boolean isProvisional(long resultCode) { return resultCode >= 1000 && resultCode < 2000; } protected boolean isSuccess(long resultCode) { return resultCode >= 2000 && resultCode < 3000; } protected boolean isFailure(long code) { return (!isProvisional(code) && !isSuccess(code) && ((code >= 3000 && code < 6000)) && !temporaryErrorCodes.contains(code)); } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#relink(org.jdiameter.client.api.IContainer) */ private Message messageFromBuffer(ByteBuffer request) throws InternalException { if (request != null) { Message m; try { m = parser.createMessage(request); return m; } catch (AvpDataException e) { throw new InternalException("Failed to decode message.", e); } } return null; } private ByteBuffer messageToBuffer(IMessage msg) throws InternalException { try { return parser.encodeMessage(msg); } catch (ParseException e) { throw new InternalException("Failed to encode message.", e); } } private class RequestDelivery implements Runnable { ClientRxSession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case RxReAuthRequest.code: handleEvent(new Event(Event.Type.RECEIVE_RAR, factory.createReAuthRequest(request), null)); break; case RxAbortSessionRequest.code: handleEvent(new Event(Event.Type.RECEIVE_ASR, factory.createAbortSessionRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failure processing request", e); } } } private class AnswerDelivery implements Runnable { ClientRxSession session; Answer answer; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case RxAAAnswer.code: final RxAARequest myAARequest = factory.createAARequest(request); final RxAAAnswer myAAAnswer = factory.createAAAnswer(answer); handleEvent(new Event(false, myAARequest, myAAAnswer)); break; case RxSessionTermAnswer.code: final RxSessionTermRequest mySTRequest = factory.createSessionTermRequest(request); final RxSessionTermAnswer mySTAnswer = factory.createSessionTermAnswer(answer); handleEvent(new Event(false, mySTRequest, mySTAnswer)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failure processing success message", e); } } } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(authAppIds); result = prime * result + (isEventBased ? 1231 : 1237); result = prime * result + ((originHost == null) ? 0 : originHost.hashCode()); result = prime * result + ((originRealm == null) ? 0 : originRealm.hashCode()); result = prime * result + ((sessionData == null) ? 0 : (sessionData.getClientRxSessionState() == null ? 0 : sessionData.getClientRxSessionState().hashCode())); return result; } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ClientRxSessionImpl other = (ClientRxSessionImpl) obj; if (!Arrays.equals(authAppIds, other.authAppIds)) { return false; } if (isEventBased != other.isEventBased) { return false; } if (originHost == null) { if (other.originHost != null) { return false; } } else if (!originHost.equals(other.originHost)) { return false; } if (originRealm == null) { if (other.originRealm != null) { return false; } } else if (!originRealm.equals(other.originRealm)) { return false; } if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (sessionData.getClientRxSessionState() == null) { if (other.sessionData.getClientRxSessionState() != null) { return false; } } else if (!sessionData.getClientRxSessionState().equals(other.sessionData.getClientRxSessionState())) { return false; } return true; } @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/rx/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.rx; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.rx.events.RxAAAnswer; import org.jdiameter.api.rx.events.RxAARequest; import org.jdiameter.api.rx.events.RxAbortSessionAnswer; import org.jdiameter.api.rx.events.RxAbortSessionRequest; import org.jdiameter.api.rx.events.RxReAuthAnswer; import org.jdiameter.api.rx.events.RxReAuthRequest; import org.jdiameter.api.rx.events.RxSessionTermAnswer; import org.jdiameter.api.rx.events.RxSessionTermRequest; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { public enum Type { SEND_AAR, RECEIVE_AAA, SEND_STR, RECEIVE_STA, SEND_RAA, RECEIVE_RAR, SEND_ASA, RECEIVE_ASR, SEND_EVENT_REQUEST, RECEIVE_EVENT_ANSWER; } Type type; AppRequestEvent request; AppAnswerEvent answer; Event(Type type) { this.type = type; } Event(Type type, AppRequestEvent request, AppAnswerEvent answer) { this.type = type; this.answer = answer; this.request = request; } Event(boolean isRequest, AppRequestEvent request, AppAnswerEvent answer) throws AvpDataException { this.answer = answer; this.request = request; if (isRequest) { switch (request.getCommandCode()) { case RxAARequest.code: type = Type.SEND_AAR; break; case RxSessionTermRequest.code: type = Type.SEND_STR; break; case RxReAuthRequest.code: type = Type.RECEIVE_RAR; break; case RxAbortSessionRequest.code: type = Type.RECEIVE_ASR; break; case 5: //BUG FIX How do we know this is an event and not a session? Do we need to fix this? Does Rx do event? type = Type.SEND_EVENT_REQUEST; break; default: throw new RuntimeException("Wrong command code value: " + request.getCommandCode()); } } else { switch (answer.getCommandCode()) { case RxAAAnswer.code: type = Type.RECEIVE_AAA; break; case RxSessionTermAnswer.code: type = Type.RECEIVE_STA; break; case RxReAuthAnswer.code: type = Type.SEND_RAA; break; case RxAbortSessionAnswer.code: type = Type.SEND_ASA; case 6: //BUG FIX How do we know this is an event and not a session? Do we need to fix this? Does Rx do event? type = Type.RECEIVE_EVENT_ANSWER; break; default: throw new RuntimeException("Wrong CC-Request-Type value: " + answer.getCommandCode()); } } } @Override public Enum getType() { return type; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { // FIXME: What should we do here?! Is it request or answer? } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public E encodeType(Class eClass) { return eClass == Event.Type.class ? (E) type : null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/rx/IClientRxSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.rx; import org.jdiameter.common.api.app.rx.ClientRxSessionState; import org.jdiameter.common.api.app.rx.IRxSessionData; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IClientRxSessionData extends IRxSessionData { boolean isEventBased(); void setEventBased(boolean b); boolean isRequestTypeSet(); void setRequestTypeSet(boolean b); ClientRxSessionState getClientRxSessionState(); void setClientRxSessionState(ClientRxSessionState state); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/s13/ClientS13SessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.app.s13; import org.jdiameter.common.impl.app.s13.S13LocalSessionDataImpl; @SuppressWarnings("all") //3rd party lib public class ClientS13SessionDataLocalImpl extends S13LocalSessionDataImpl implements IClientS13SessionData { public ClientS13SessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/s13/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.app.s13; import org.jdiameter.api.InternalException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_ECA; } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { try { if (((AppEvent) data).getMessage().isRequest()) { request = (AppEvent) data; } else { answer = (AppEvent) data; } } catch (InternalException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/s13/IClientS13SessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.app.s13; import org.jdiameter.common.api.app.s13.IS13SessionData; @SuppressWarnings("all") //3rd party lib public interface IClientS13SessionData extends IS13SessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/s13/S13ClientSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.app.s13; import org.jdiameter.api.*; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.s13.ClientS13Session; import org.jdiameter.api.s13.ClientS13SessionListener; import org.jdiameter.api.s13.events.JMEIdentityCheckAnswer; import org.jdiameter.api.s13.events.JMEIdentityCheckRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.s13.Event.Type; import org.jdiameter.common.api.app.s13.IS13MessageFactory; import org.jdiameter.common.api.app.s13.S13SessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.s13.S13Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings("all") //3rd party lib public class S13ClientSessionImpl extends S13Session implements ClientS13Session, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(S13ClientSessionImpl.class); private transient ClientS13SessionListener listener; protected long appId = -1; protected IClientS13SessionData sessionData; public S13ClientSessionImpl(IClientS13SessionData sessionData, IS13MessageFactory fct, ISessionFactory sf, ClientS13SessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationId() < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.appId = fct.getApplicationId(); this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == S13SessionState.class ? (E) this.sessionData.getS13SessionState() : null; } public void setListener(ClientS13SessionListener listener) { this.listener = listener; } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void sendMEIdentityCheckRequest(JMEIdentityCheckRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } @Override public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final S13SessionState state = this.sessionData.getS13SessionState(); S13SessionState newState = null; Event localEvent = (Event) event; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case SEND_MESSAGE: newState = S13SessionState.MESSAGE_SENT_RECEIVED; super.session.send(((AppEvent) event.getData()).getMessage(), this); setState(newState); // FIXME: is this ok to be here? break; default: logger.error("Invalid Event Type {} for S13 Client Session at state {}.", eventType, sessionData.getS13SessionState()); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = S13SessionState.TIMEDOUT; setState(newState); break; case SEND_MESSAGE: try { super.session.send(((AppEvent) event.getData()).getMessage(), this); } finally { newState = S13SessionState.TERMINATED; setState(newState); } break; case RECEIVE_ECA: newState = S13SessionState.TERMINATED; setState(newState); super.cancelMsgTimer(); listener.doMEIdentityCheckAnswerEvent(this, (JMEIdentityCheckRequest) localEvent.getRequest(), (JMEIdentityCheckAnswer) localEvent.getAnswer()); break; default: throw new InternalException("Unexpected/Unknown message received: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("S13 Client FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } @SuppressWarnings("unchecked") protected void setState(S13SessionState newState) { S13SessionState oldState = this.sessionData.getS13SessionState(); this.sessionData.setS13SessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == S13SessionState.TERMINATED || newState == S13SessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); } } @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(S13Session.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (int) (appId ^ (appId >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } S13ClientSessionImpl other = (S13ClientSessionImpl) obj; if (appId != other.appId) { return false; } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ClientS13Session session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ClientS13Session session; Answer answer; Request request; @Override public void run() { try { switch (answer.getCommandCode()) { case JMEIdentityCheckAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_ECA, messageFactory.createMEIdentityCheckRequest(request), messageFactory.createMEIdentityCheckAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/s6a/ClientS6aSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.s6a; import org.jdiameter.common.impl.app.s6a.S6aLocalSessionDataImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ClientS6aSessionDataLocalImpl extends S6aLocalSessionDataImpl implements IClientS6aSessionData { public ClientS6aSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/s6a/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.s6a; import org.jdiameter.api.InternalException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_AIA, RECEIVE_PUA, RECEIVE_ULA, RECEIVE_NOA, RECEIVE_CLR, RECEIVE_IDR, RECEIVE_DSR, RECEIVE_RSR; } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { try { if (((AppEvent) data).getMessage().isRequest()) { request = (AppEvent) data; } else { answer = (AppEvent) data; } } catch (InternalException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/s6a/IClientS6aSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.s6a; import org.jdiameter.common.api.app.s6a.IS6aSessionData; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientS6aSessionData extends IS6aSessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/s6a/S6aClientSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.s6a; import org.jdiameter.api.*; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.s6a.ClientS6aSession; import org.jdiameter.api.s6a.ClientS6aSessionListener; import org.jdiameter.api.s6a.events.*; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.s6a.Event.Type; import org.jdiameter.common.api.app.s6a.IS6aMessageFactory; import org.jdiameter.common.api.app.s6a.S6aSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.s6a.S6aSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Diameter S6a Client Session implementation * * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class S6aClientSessionImpl extends S6aSession implements ClientS6aSession, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(S6aClientSessionImpl.class); // Factories and Listeners -------------------------------------------------- private transient ClientS6aSessionListener listener; protected long appId = -1; protected IClientS6aSessionData sessionData; public S6aClientSessionImpl(IClientS6aSessionData sessionData, IS6aMessageFactory fct, ISessionFactory sf, ClientS6aSessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationId() < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.appId = fct.getApplicationId(); this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } public void setListener(ClientS6aSessionListener listener) { this.listener = listener; } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateMachine#getState(java.lang.Class) */ @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == S6aSessionState.class ? (E) this.sessionData.getS6aSessionState() : null; } /* * (non-Javadoc) * * @see org.jdiameter.api.NetworkReqListener#processRequest(org.jdiameter.api.Request) */ @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void sendAuthenticationInformationRequest(JAuthenticationInformationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } @Override public void sendPurgeUERequest(JPurgeUERequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } @Override public void sendNotifyRequest(JNotifyRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } @Override public void sendUpdateLocationRequest(JUpdateLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } @Override public void sendCancelLocationAnswer(JCancelLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } @Override public void sendInsertSubscriberDataAnswer(JInsertSubscriberDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } @Override public void sendDeleteSubscriberDataAnswer(JDeleteSubscriberDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } @Override public void sendResetAnswer(JResetAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } /* * (non-Javadoc) * * @see org.jdiameter.api.EventListener#receivedSuccessMessage(org.jdiameter.api.Message, org.jdiameter.api.Message) */ @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } /* * (non-Javadoc) * * @see * org.jdiameter.api.EventListener#timeoutExpired(org.jdiameter.api.Message) */ @Override public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final S6aSessionState state = this.sessionData.getS6aSessionState(); S6aSessionState newState = null; Event localEvent = (Event) event; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVE_CLR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.startMsgTimer(); newState = S6aSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doCancelLocationRequestEvent(this, (JCancelLocationRequest) event.getData()); break; case RECEIVE_IDR: newState = S6aSessionState.MESSAGE_SENT_RECEIVED; setState(newState); this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.startMsgTimer(); listener.doInsertSubscriberDataRequestEvent(this, (JInsertSubscriberDataRequest) event.getData()); break; case RECEIVE_DSR: newState = S6aSessionState.MESSAGE_SENT_RECEIVED; setState(newState); this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.startMsgTimer(); listener.doDeleteSubscriberDataRequestEvent(this, (JDeleteSubscriberDataRequest) event.getData()); break; case RECEIVE_RSR: newState = S6aSessionState.MESSAGE_SENT_RECEIVED; setState(newState); this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.startMsgTimer(); listener.doResetRequestEvent(this, (JResetRequest) event.getData()); break; case SEND_MESSAGE: newState = S6aSessionState.MESSAGE_SENT_RECEIVED; super.session.send(((AppEvent) event.getData()).getMessage(), this); setState(newState); //FIXME: is this ok to be here? break; default: logger.error("Invalid Event Type {} for S6a Client Session at state {}.", eventType, sessionData.getS6aSessionState()); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = S6aSessionState.TIMEDOUT; setState(newState); break; case SEND_MESSAGE: try { super.session.send(((AppEvent) event.getData()).getMessage(), this); } finally { newState = S6aSessionState.TERMINATED; setState(newState); } break; case RECEIVE_ULA: newState = S6aSessionState.TERMINATED; setState(newState); super.cancelMsgTimer(); listener.doUpdateLocationAnswerEvent(this, (JUpdateLocationRequest) localEvent.getRequest(), (JUpdateLocationAnswer) localEvent.getAnswer()); break; case RECEIVE_AIA: newState = S6aSessionState.TERMINATED; setState(newState); super.cancelMsgTimer(); listener.doAuthenticationInformationAnswerEvent(this, (JAuthenticationInformationRequest) localEvent.getRequest(), (JAuthenticationInformationAnswer) localEvent.getAnswer()); break; case RECEIVE_PUA: newState = S6aSessionState.TERMINATED; setState(newState); super.cancelMsgTimer(); listener.doPurgeUEAnswerEvent(this, (JPurgeUERequest) localEvent.getRequest(), (JPurgeUEAnswer) localEvent.getAnswer()); break; case RECEIVE_NOA: newState = S6aSessionState.TERMINATED; setState(newState); super.cancelMsgTimer(); listener.doNotifyAnswerEvent(this, (JNotifyRequest) localEvent.getRequest(), (JNotifyAnswer) localEvent.getAnswer()); break; default: throw new InternalException("Unexpected/Unknown message received: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("S6a Client FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } @SuppressWarnings("unchecked") protected void setState(S6aSessionState newState) { S6aSessionState oldState = this.sessionData.getS6aSessionState(); this.sessionData.setS6aSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == S6aSessionState.TERMINATED || newState == S6aSessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(S6aSession.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.s6a.S6aSession#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (int) (appId ^ (appId >>> 32)); return result; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.s6a.S6aSession#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } S6aClientSessionImpl other = (S6aClientSessionImpl) obj; if (appId != other.appId) { return false; } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ClientS6aSession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case JCancelLocationRequest.code: handleEvent( new Event(Event.Type.RECEIVE_CLR, messageFactory.createCancelLocationRequest(request), null)); break; case JInsertSubscriberDataRequest.code: handleEvent(new Event(Event.Type.RECEIVE_IDR, messageFactory.createInsertSubscriberDataRequest(request), null)); break; case JDeleteSubscriberDataRequest.code: handleEvent(new Event(Event.Type.RECEIVE_DSR, messageFactory.createDeleteSubscriberDataRequest(request), null)); break; case JResetRequest.code: handleEvent(new Event(Event.Type.RECEIVE_RSR, messageFactory.createResetRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ClientS6aSession session; Answer answer; Request request; @Override public void run() { try { switch (answer.getCommandCode()) { case JUpdateLocationAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_ULA, messageFactory.createUpdateLocationRequest(request), messageFactory.createUpdateLocationAnswer(answer))); break; case JAuthenticationInformationAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_AIA, messageFactory.createAuthenticationInformationRequest(request), messageFactory.createAuthenticationInformationAnswer(answer))); break; case JPurgeUEAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_PUA, messageFactory.createPurgeUERequest(request), messageFactory.createPurgeUEAnswer(answer))); break; case JNotifyAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_NOA, messageFactory.createNotifyRequest(request), messageFactory.createNotifyAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/sh/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.sh; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_USER_DATA_REQUEST, SEND_PROFILE_UPDATE_REQUEST, SEND_SUBSCRIBE_NOTIFICATIONS_REQUEST, SEND_PUSH_NOTIFICATION_ANSWER, RECEIVE_PUSH_NOTIFICATION_REQUEST, RECEIVE_USER_DATA_ANSWER, RECEIVE_PROFILE_UPDATE_ANSWER, RECEIVE_SUBSCRIBE_NOTIFICATIONS_ANSWER, TIMEOUT_EXPIRES } Type type; AppEvent request; AppEvent answer; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { // FIXME: What should we do here?! Is it request or answer? } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/sh/IShClientSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.sh; import org.jdiameter.common.api.app.sh.IShSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IShClientSessionData extends IShSessionData { // Stateless } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/sh/ShClientSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.sh; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ShClientSessionDataLocalImpl extends AppSessionDataLocalImpl implements IShClientSessionData { /** * */ public ShClientSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/sh/ShClientSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.app.sh; import org.jdiameter.api.*; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.sh.ClientShSession; import org.jdiameter.api.sh.ClientShSessionListener; import org.jdiameter.api.sh.events.*; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.sh.IShMessageFactory; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.sh.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Basic implementation of ShClientSession - can be one time - for UDR, PUR and constant for SNR-PNR pair, in case when * SNA contains response code from range different than 2001-2004(success codes) user is responsible for maintaing state * - releasing etc, same goes if result code is contained Experimental-Result AVP
      * If ShSession moves to * ShSessionState.TERMINATED - it means that no further messages can be received via it and it should be discarded. *
      *
      * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ShClientSessionImpl extends ShSession implements ClientShSession, EventListener, NetworkReqListener { private Logger logger = LoggerFactory.getLogger(ShClientSessionImpl.class); // Session State Handling --------------------------------------------------- protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IShMessageFactory factory = null; protected transient ClientShSessionListener listener; protected IShClientSessionData sessionData; public ShClientSessionImpl(IShClientSessionData sessionData, IShMessageFactory fct, ISessionFactory sf, ClientShSessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationId() < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.listener = lst; this.factory = fct; this.sessionData = sessionData; } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } public void setListener(ClientShSessionListener listener) { this.listener = listener; } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); Event localEvent = (Event) event; // Do the delivery switch ((Event.Type) localEvent.getType()) { case RECEIVE_PUSH_NOTIFICATION_REQUEST: listener.doPushNotificationRequestEvent(this, new PushNotificationRequestImpl((Request) localEvent.getRequest().getMessage())); break; case RECEIVE_PROFILE_UPDATE_ANSWER: listener.doProfileUpdateAnswerEvent(this, (ProfileUpdateRequest) localEvent.getRequest(), new ProfileUpdateAnswerImpl((Answer) localEvent.getAnswer().getMessage())); break; case RECEIVE_USER_DATA_ANSWER: listener.doUserDataAnswerEvent(this, (UserDataRequest) localEvent.getRequest(), new UserDataAnswerImpl((Answer) localEvent.getAnswer().getMessage())); break; case RECEIVE_SUBSCRIBE_NOTIFICATIONS_ANSWER: listener.doSubscribeNotificationsAnswerEvent(this, (SubscribeNotificationsRequest) localEvent.getRequest(), new SubscribeNotificationsAnswerImpl((Answer) localEvent.getAnswer().getMessage())); break; case SEND_PROFILE_UPDATE_REQUEST: case SEND_PUSH_NOTIFICATION_ANSWER: case SEND_SUBSCRIBE_NOTIFICATIONS_REQUEST: case SEND_USER_DATA_REQUEST: Message m = null; Object data = event.getData(); m = data instanceof AppEvent ? ((AppEvent) data).getMessage() : (Message) event.getData(); session.send(m, this); break; case TIMEOUT_EXPIRES: // TODO Anything here? break; default: logger.error("Wrong message type={} req={} ans={}", new Object[]{localEvent.getType(), localEvent.getRequest(), localEvent.getAnswer()}); } } catch (IllegalDiameterStateException idse) { throw new InternalException(idse); } catch (RouteException re) { throw new InternalException(re); } finally { sendAndStateLock.unlock(); } return true; } @Override public void sendProfileUpdateRequest(ProfileUpdateRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_PROFILE_UPDATE_REQUEST, request, null); } @Override public void sendPushNotificationAnswer(PushNotificationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_PUSH_NOTIFICATION_ANSWER, null, answer); } @Override public void sendSubscribeNotificationsRequest(SubscribeNotificationsRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_SUBSCRIBE_NOTIFICATIONS_REQUEST, request, null); } @Override public void sendUserDataRequest(UserDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_USER_DATA_REQUEST, request, null); } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { sendAndStateLock.lock(); if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } @Override public void timeoutExpired(Request request) { try { if (request.getApplicationId() == factory.getApplicationId()) { if (request.getCommandCode() == ProfileUpdateRequest.code) { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, factory.createProfileUpdateRequest(request), null)); return; } else if (request.getCommandCode() == UserDataRequest.code) { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, factory.createUserDataRequest(request), null)); return; } else if (request.getCommandCode() == SubscribeNotificationsRequest.code) { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, factory.createSubscribeNotificationsRequest(request), null)); return; } } } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } @Override public boolean isStateless() { return true; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } private class RequestDelivery implements Runnable { ClientShSession session; Request request; @Override public void run() { try { if (request.getApplicationId() == factory.getApplicationId()) { if (request.getCommandCode() == PushNotificationRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_PUSH_NOTIFICATION_REQUEST, factory.createPushNotificationRequest(request), null)); return; } } listener.doOtherEvent(session, new AppRequestEventImpl(request), null); } catch (Exception e) { logger.debug("Failed to process request {}", request, e); } } } private class AnswerDelivery implements Runnable { ClientShSession session; Answer answer; Request request; @Override public void run() { try { sendAndStateLock.lock(); if (request.getApplicationId() == factory.getApplicationId()) { if (request.getCommandCode() == ProfileUpdateRequest.code) { handleEvent( new Event(Event.Type.RECEIVE_PROFILE_UPDATE_ANSWER, factory.createProfileUpdateRequest(request), factory.createProfileUpdateAnswer(answer))); return; } else if (request.getCommandCode() == UserDataRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_USER_DATA_ANSWER, factory.createUserDataRequest(request), factory.createUserDataAnswer(answer))); return; } else if (request.getCommandCode() == SubscribeNotificationsRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_SUBSCRIBE_NOTIFICATIONS_ANSWER, factory.createSubscribeNotificationsRequest(request), factory .createSubscribeNotificationsAnswer(answer))); return; } } listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); } catch (Exception e) { logger.debug("Failed to process success message", e); } finally { sendAndStateLock.unlock(); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/ClientSLgSessionDataLocalImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.client.impl.app.slg; import org.jdiameter.common.impl.app.slg.SLgLocalSessionDataImpl; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class ClientSLgSessionDataLocalImpl extends SLgLocalSessionDataImpl implements IClientSLgSessionData { public ClientSLgSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/Event.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.client.impl.app.slg; import org.jdiameter.api.InternalException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_PLA, RECEIVE_LRR } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @SuppressWarnings("unchecked") public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @SuppressWarnings("rawtypes") public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } public int compareTo(Object o) { return 0; } public Object getData() { return request != null ? request : answer; } public void setData(Object data) { try { if (((AppEvent) data).getMessage().isRequest()) { request = (AppEvent) data; } else { answer = (AppEvent) data; } } catch (InternalException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/IClientSLgSessionData.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.client.impl.app.slg; import org.jdiameter.common.api.app.slg.ISLgSessionData; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface IClientSLgSessionData extends ISLgSessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/SLgClientSessionImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.client.impl.app.slg; import org.jdiameter.api.*; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.slg.ClientSLgSession; import org.jdiameter.api.slg.ClientSLgSessionListener; import org.jdiameter.api.slg.events.LocationReportAnswer; import org.jdiameter.api.slg.events.LocationReportRequest; import org.jdiameter.api.slg.events.ProvideLocationAnswer; import org.jdiameter.api.slg.events.ProvideLocationRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.slg.Event.Type; import org.jdiameter.common.api.app.slg.ISLgMessageFactory; import org.jdiameter.common.api.app.slg.SLgSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.slg.SLgSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLgClientSessionImpl extends SLgSession implements ClientSLgSession, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(SLgClientSessionImpl.class); private transient ClientSLgSessionListener listener; protected long appId = -1; protected IClientSLgSessionData sessionData; public SLgClientSessionImpl(IClientSLgSessionData sessionData, ISLgMessageFactory fct, ISessionFactory sf, ClientSLgSessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationId() < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.appId = fct.getApplicationId(); this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } public void setListener(ClientSLgSessionListener listener) { this.listener = listener; } @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == SLgSessionState.class ? (E) this.sessionData.getSLgSessionState() : null; } public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } public void sendProvideLocationRequest(ProvideLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } public void sendLocationReportAnswer(LocationReportAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final SLgSessionState state = this.sessionData.getSLgSessionState(); SLgSessionState newState; Event localEvent = (Event) event; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case SEND_MESSAGE: newState = SLgSessionState.MESSAGE_SENT_RECEIVED; super.session.send(((AppEvent) event.getData()).getMessage(), this); setState(newState); // FIXME: is this ok to be here? break; case RECEIVE_LRR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = SLgSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doLocationReportRequestEvent(this, (LocationReportRequest) event.getData()); break; default: logger.error("Invalid Event Type {} for SLg Client Session at state {}.", eventType, sessionData.getSLgSessionState()); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = SLgSessionState.TIMEDOUT; setState(newState); break; case SEND_MESSAGE: try { super.session.send(((AppEvent) event.getData()).getMessage(), this); } finally { newState = SLgSessionState.TERMINATED; setState(newState); } break; case RECEIVE_PLA: newState = SLgSessionState.TERMINATED; setState(newState); listener.doProvideLocationAnswerEvent(this, (ProvideLocationRequest) localEvent.getRequest(), (ProvideLocationAnswer) localEvent.getAnswer()); break; default: throw new InternalException("Unexpected/Unknown message received: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("SLg Client FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } @SuppressWarnings({"unchecked", "rawtypes"}) protected void setState(SLgSessionState newState) { SLgSessionState oldState = this.sessionData.getSLgSessionState(); this.sessionData.setSLgSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == SLgSessionState.TERMINATED || newState == SLgSessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); } } public void onTimer(String timerName) { if (timerName.equals(SLgSession.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (int) (appId ^ (appId >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } SLgClientSessionImpl other = (SLgClientSessionImpl) obj; if (appId != other.appId) { return false; } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ClientSLgSession session; Request request; public void run() { try { switch (request.getCommandCode()) { case LocationReportRequest.code: handleEvent( new Event(Event.Type.RECEIVE_LRR, messageFactory.createLocationReportRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ClientSLgSession session; Answer answer; Request request; public void run() { try { switch (answer.getCommandCode()) { case ProvideLocationAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_PLA, messageFactory.createProvideLocationRequest(request), messageFactory.createProvideLocationAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/ClientSLhSessionDataLocalImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.client.impl.app.slh; import org.jdiameter.common.impl.app.slh.SLhLocalSessionDataImpl; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class ClientSLhSessionDataLocalImpl extends SLhLocalSessionDataImpl implements IClientSLhSessionData { public ClientSLhSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/Event.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.client.impl.app.slh; import org.jdiameter.api.InternalException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_RIA; } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @SuppressWarnings("unchecked") public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @SuppressWarnings("rawtypes") public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } public int compareTo(Object o) { return 0; } public Object getData() { return request != null ? request : answer; } public void setData(Object data) { try { if (((AppEvent) data).getMessage().isRequest()) { request = (AppEvent) data; } else { answer = (AppEvent) data; } } catch (InternalException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/IClientSLhSessionData.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.client.impl.app.slh; import org.jdiameter.common.api.app.slh.ISLhSessionData; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface IClientSLhSessionData extends ISLhSessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/SLhClientSessionImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.client.impl.app.slh; import org.jdiameter.api.*; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.slh.ClientSLhSession; import org.jdiameter.api.slh.ClientSLhSessionListener; import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.slh.Event.Type; import org.jdiameter.common.api.app.slh.ISLhMessageFactory; import org.jdiameter.common.api.app.slh.SLhSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.slh.SLhSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLhClientSessionImpl extends SLhSession implements ClientSLhSession, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(SLhClientSessionImpl.class); private transient ClientSLhSessionListener listener; protected long appId = -1; protected IClientSLhSessionData sessionData; public SLhClientSessionImpl(IClientSLhSessionData sessionData, ISLhMessageFactory fct, ISessionFactory sf, ClientSLhSessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationId() < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.appId = fct.getApplicationId(); this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } public void setListener(ClientSLhSessionListener listener) { this.listener = listener; } @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == SLhSessionState.class ? (E) this.sessionData.getSLhSessionState() : null; } public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } public void sendLCSRoutingInfoRequest(LCSRoutingInfoRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final SLhSessionState state = this.sessionData.getSLhSessionState(); SLhSessionState newState; Event localEvent = (Event) event; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case SEND_MESSAGE: newState = SLhSessionState.MESSAGE_SENT_RECEIVED; super.session.send(((AppEvent) event.getData()).getMessage(), this); setState(newState); // FIXME: is this ok to be here? break; default: logger.error("Invalid Event Type {} for SLh Client Session at state {}.", eventType, sessionData.getSLhSessionState()); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = SLhSessionState.TIMEDOUT; setState(newState); break; case SEND_MESSAGE: try { super.session.send(((AppEvent) event.getData()).getMessage(), this); } finally { newState = SLhSessionState.TERMINATED; setState(newState); } break; case RECEIVE_RIA: newState = SLhSessionState.TERMINATED; setState(newState); listener.doLCSRoutingInfoAnswerEvent(this, (LCSRoutingInfoRequest) localEvent.getRequest(), (LCSRoutingInfoAnswer) localEvent.getAnswer()); break; default: throw new InternalException("Unexpected/Unknown message received: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("SLh Client FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } @SuppressWarnings({"unchecked", "rawtypes"}) protected void setState(SLhSessionState newState) { SLhSessionState oldState = this.sessionData.getSLhSessionState(); this.sessionData.setSLhSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == SLhSessionState.TERMINATED || newState == SLhSessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); } } public void onTimer(String timerName) { if (timerName.equals(SLhSession.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (int) (appId ^ (appId >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } SLhClientSessionImpl other = (SLhClientSessionImpl) obj; if (appId != other.appId) { return false; } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ClientSLhSession session; Request request; public void run() { try { switch (request.getCommandCode()) { default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ClientSLhSession session; Answer answer; Request request; public void run() { try { switch (answer.getCommandCode()) { case LCSRoutingInfoAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_RIA, messageFactory.createLCSRoutingInfoRequest(request), messageFactory.createLCSRoutingInfoAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.controller; import static org.jdiameter.api.Avp.*; import static org.jdiameter.api.Message.*; import static org.jdiameter.client.api.fsm.EventTypes.*; import static org.jdiameter.client.impl.helpers.Parameters.SecurityRef; import static org.jdiameter.client.impl.helpers.Parameters.UseUriAsFqdn; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Configuration; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Peer; import org.jdiameter.api.PeerState; import org.jdiameter.api.PeerStateListener; import org.jdiameter.api.ResultCode; import org.jdiameter.api.RouteException; import org.jdiameter.api.URI; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IMetaData; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.fsm.EventTypes; import org.jdiameter.client.api.fsm.FsmEvent; import org.jdiameter.client.api.fsm.IContext; import org.jdiameter.client.api.fsm.IFsmFactory; import org.jdiameter.client.api.fsm.IStateMachine; import org.jdiameter.client.api.io.IConnection; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.ITransportLayerFactory; import org.jdiameter.client.api.io.TransportError; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.router.IRouter; import org.jdiameter.client.impl.AbstractStateChangeListener; import org.jdiameter.client.impl.DictionarySingleton; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.jdiameter.common.impl.controller.AbstractPeer; import org.jdiameter.server.impl.MutablePeerTableImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Client Peer implementation * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class PeerImpl extends AbstractPeer implements IPeer { private static final Logger logger = LoggerFactory.getLogger(PeerImpl.class); // Properties protected InetAddress[] addresses; protected String realmName; protected long vendorID; protected String productName; protected int firmWare; protected Set commonApplications = new HashSet(); protected AtomicLong hopByHopId = new AtomicLong(uid.nextInt()); protected int rating; protected boolean stopping = false; // Members protected IMetaData metaData; protected PeerTableImpl table; // Facilities protected IRouter router; // XXX: FT/HA // protected Map slc; protected final Map peerRequests = new ConcurrentHashMap(); protected final Dictionary dictionary = DictionarySingleton.getDictionary(); // FSM layer protected IStateMachine fsm; protected IMessageParser parser; // Feature protected boolean useUriAsFQDN = false; // Use URI as origin host name into CER command //session store and data protected ISessionDatasource sessionDataSource; // Transport layer protected IConnection connection; protected IConnectionListener connListener = new IConnectionListener() { @Override public void connectionOpened(String connKey) { logger.debug("Connection to {} is open", uri); try { fsm.handleEvent(new FsmEvent(CONNECT_EVENT, connKey)); } catch (Exception e) { logger.warn("Unable to run start procedure", e); } } @Override public void connectionClosed(String connKey, List notSent) { logger.debug("Connection from {} is closed", uri); for (IMessage request : peerRequests.values()) { if (request.getState() == IMessage.STATE_SENT) { request.setReTransmitted(true); request.setState(IMessage.STATE_NOT_SENT); try { peerRequests.remove(request.getHopByHopIdentifier()); table.sendMessage(request); } catch (Throwable exc) { request.setReTransmitted(false); } } } try { fsm.handleEvent(new FsmEvent(DISCONNECT_EVENT, connKey)); } catch (Exception e) { logger.warn("Unable to run stopping procedure", e); } } @Override public void messageReceived(String connKey, IMessage message) { boolean req = message.isRequest(); try { int type = message.getCommandCode(); logger.debug("Receive message type [{}] to peer [{}]", new Object[] { type, connKey }); switch (type) { case CAPABILITIES_EXCHANGE_REQUEST: fsm.handleEvent(new FsmEvent(req ? CER_EVENT : CEA_EVENT, message, connKey)); break; case DEVICE_WATCHDOG_REQUEST: fsm.handleEvent(new FsmEvent(req ? DWR_EVENT : DWA_EVENT, message, connKey)); break; case DISCONNECT_PEER_REQUEST: fsm.handleEvent(new FsmEvent(req ? DPR_EVENT : DPA_EVENT, message)); break; default: fsm.handleEvent(new FsmEvent(RECEIVE_MSG_EVENT, message)); break; } } catch (Exception e) { logger.warn("Error while processing incoming message", e); if (req) { try { message.setRequest(false); message.setError(true); message.getAvps().addAvp(Avp.RESULT_CODE, ResultCode.TOO_BUSY, true); connection.sendMessage(message); } catch (Exception exc) { logger.warn("Unable to send error answer", exc); } } } } @Override public void internalError(String connKey, IMessage message, TransportException cause) { try { logger.debug("internalError ", cause); fsm.handleEvent(new FsmEvent(INTERNAL_ERROR, message)); } catch (Exception e) { logger.debug("Unable to run internalError procedure", e); } } }; public PeerImpl(final PeerTableImpl table, int rating, URI remotePeer, String ip, String portRange, IMetaData metaData, Configuration config, Configuration peerConfig, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, IMessageParser parser, final ISessionDatasource sessionDataSource) throws InternalException, TransportException { this(table, rating, remotePeer, ip, portRange, metaData, config, peerConfig, fsmFactory, trFactory, parser, statisticFactory, concurrentFactory, null, sessionDataSource); } protected PeerImpl(final PeerTableImpl table, int rating, URI remotePeer, String ip, String portRange, IMetaData metaData, Configuration config, Configuration peerConfig, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, IMessageParser parser, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, IConnection connection, final ISessionDatasource sessionDataSource) throws InternalException, TransportException { super(remotePeer, statisticFactory); this.table = table; this.rating = rating; this.router = table.router; this.metaData = metaData; // XXX: FT/HA // this.slc = table.getSessionReqListeners(); this.sessionDataSource = sessionDataSource; int port = remotePeer.getPort(); InetAddress remoteAddress; try { remoteAddress = InetAddress.getByName(ip != null ? ip : remotePeer.getFQDN()); } catch (UnknownHostException e) { throw new TransportException("Unable to retrieve host", TransportError.Internal, e); } IContext actionContext = getContext(); this.fsm = fsmFactory.createInstanceFsm(actionContext, concurrentFactory, config); this.fsm.addStateChangeNotification( new AbstractStateChangeListener() { @Override public void stateChanged(Enum oldState, Enum newState) { PeerState s = (PeerState) newState; if (PeerState.DOWN.equals(s)) { stopping = false; } } }); if (connection == null) { String ref = peerConfig.getStringValue(SecurityRef.ordinal(), null); InetAddress localAddress = null; try { Peer local = metaData.getLocalPeer(); if (local.getIPAddresses() != null && local.getIPAddresses().length > 0) { localAddress = local.getIPAddresses()[0]; } else { localAddress = InetAddress.getByName(metaData.getLocalPeer().getUri().getFQDN()); } } catch (Exception e) { logger.warn("Unable to get local address", e); } int localPort = 0; if (portRange != null) { try { String[] rng = portRange.trim().split("-"); int startRange = Integer.parseInt(rng[0]); int endRange = Integer.parseInt(rng[1]); boolean portNotAvailable = false; int limit = 0; int maxTries = endRange - startRange + 1; logger.debug( "Selecting local port randomly from range '{}-{}'. Doing {} tries (some ports may not be tested, others tested more than once).", new Object[] { startRange, endRange, maxTries }); do { portNotAvailable = false; limit++; localPort = startRange + new Random().nextInt(endRange - startRange + 1); logger.trace("Checking if port '{}' is available.", localPort); //check if port is open ServerSocket socket = null; try { socket = new ServerSocket(localPort); socket.setReuseAddress(true); } catch (IOException e) { logger.trace("The port '{}' is NOT available.", localPort); portNotAvailable = true; } finally { // Clean up if (socket != null) { logger.trace("The port '{}' is available and will be used.", localPort); socket.close(); } } } while (portNotAvailable && (limit < maxTries)); if (portNotAvailable) { logger.warn("Unable to find available port in port range."); } } catch (Exception exc) { logger.warn("Unable to get local port.", exc); } logger.debug("Create connection with localAddress=[{}]; localPort=[{}]", localAddress, localPort); } this.connection = trFactory.createConnection(remoteAddress, concurrentFactory, port, localAddress, localPort, connListener, ref); } else { this.connection = connection; this.connection.addConnectionListener(connListener); } this.parser = parser; this.addresses = new InetAddress[] { remoteAddress }; this.useUriAsFQDN = config.getBooleanValue(UseUriAsFqdn.ordinal(), (Boolean) UseUriAsFqdn.defValue()); } public IContext getContext() { return new ActionContext(); } private boolean isRedirectAnswer(Avp avpResCode, IMessage answer) { try { return (answer.getFlags() & 0x20) != 0 && avpResCode != null && avpResCode.getInteger32() == ResultCode.REDIRECT_INDICATION; } catch (AvpDataException e) { return false; } } @Override public IStatistic getStatistic() { return statistic; } @Override public void addPeerStateListener(final PeerStateListener listener) { fsm.addStateChangeNotification(new AbstractStateChangeListener() { @Override public void stateChanged(Enum oldState, Enum newState) { listener.stateChanged((PeerState) oldState, (PeerState) newState); } @Override public int hashCode() { return listener.hashCode(); } @Override public boolean equals(Object obj) { return listener.equals(obj); } }); } @Override public void removePeerStateListener(final PeerStateListener listener) { //FIXME: fix this... cmon if (listener != null) { fsm.remStateChangeNotification(new AbstractStateChangeListener() { @Override public void stateChanged(Enum oldState, Enum newState) { listener.stateChanged((PeerState) oldState, (PeerState) newState); } @Override public int hashCode() { return listener.hashCode(); } @Override public boolean equals(Object obj) { return listener.equals(obj); } }); } } private IMessage processRedirectAnswer(IMessage request, IMessage answer) { int resultCode = ResultCode.SUCCESS; try { //it will try to find next hope and send it... router.processRedirectAnswer(request, answer, table); return null; } catch (RouteException exc) { // Loop detected (may be stack must send error response to redirect host) if (logger.isDebugEnabled()) { logger.debug("Failed to process redirect!", exc); } resultCode = ResultCode.LOOP_DETECTED; } catch (Throwable exc) { // Incorrect redirect message logger.debug("Failed to process redirect!", exc); resultCode = ResultCode.UNABLE_TO_DELIVER; } //why, oh why, peer works as router?.... // // Update destination avps // if (resultCode == ResultCode.SUCCESS) { // // Clear avps // answer.getAvps().removeAvp(RESULT_CODE); // // Update flags // answer.setRequest(true); // answer.setError(false); // try { // table.sendMessage(answer); // answer = null; // } // catch (Exception e) { // logger.warn("Unable to deliver due to error", e); // resultCode = ResultCode.UNABLE_TO_DELIVER; // } // } if (resultCode != ResultCode.SUCCESS) { // Restore answer flag answer.setRequest(false); answer.setError(true); answer.getAvps().removeAvp(RESULT_CODE); answer.getAvps().addAvp(RESULT_CODE, resultCode, true, false, true); } return answer; } @Override public void connect() throws InternalException, IOException, IllegalDiameterStateException { if (getState(PeerState.class) != PeerState.DOWN) { throw new IllegalDiameterStateException("Invalid state:" + getState(PeerState.class)); } try { fsm.handleEvent(new FsmEvent(EventTypes.START_EVENT)); } catch (Exception e) { throw new InternalException(e); } } @Override public void disconnect(int disconnectCause) throws InternalException, IllegalDiameterStateException { super.disconnect(disconnectCause); if (getState(PeerState.class) != PeerState.DOWN) { stopping = true; try { FsmEvent event = new FsmEvent(STOP_EVENT); event.setData(disconnectCause); fsm.handleEvent(event); } catch (OverloadException e) { stopping = false; logger.warn("Error during stopping procedure", e); } } } @Override public E getState(Class enumc) { return fsm.getState(enumc); } @Override public URI getUri() { return uri; } @Override public InetAddress[] getIPAddresses() { return addresses; } @Override public String getRealmName() { return realmName; } @Override public long getVendorId() { return vendorID; } @Override public String getProductName() { return productName; } @Override public long getFirmware() { return firmWare; } @Override public Set getCommonApplications() { return commonApplications; } @Override public long getHopByHopIdentifier() { return hopByHopId.incrementAndGet(); } @Override public void addMessage(IMessage message) { peerRequests.put(message.getHopByHopIdentifier(), message); } @Override public void remMessage(IMessage message) { peerRequests.remove(message.getHopByHopIdentifier()); } @Override public IMessage[] remAllMessage() { IMessage[] m = peerRequests.values().toArray(new IMessage[peerRequests.size()]); peerRequests.clear(); return m; } @Override public boolean handleMessage(EventTypes type, IMessage message, String key) throws TransportException, OverloadException, InternalException { return !stopping && fsm.handleEvent(new FsmEvent(type, message, key)); } @Override public boolean sendMessage(IMessage message) throws TransportException, OverloadException, InternalException { if (dictionary != null && dictionary.isEnabled()) { logger.debug("Message validation is ENABLED. Going to validate message before sending."); dictionary.validate(message, false); } return !stopping && fsm.handleEvent(new FsmEvent(EventTypes.SEND_MSG_EVENT, message)); } @Override public boolean hasValidConnection() { return connection != null && connection.isConnected(); } @Override public void setRealm(String realm) { realmName = realm; } @Override public void addStateChangeListener(StateChangeListener listener) { fsm.addStateChangeNotification(listener); } @Override public void remStateChangeListener(StateChangeListener listener) { fsm.remStateChangeNotification(listener); } @Override public void addConnectionListener(IConnectionListener listener) { if (connection != null) { connection.addConnectionListener(listener); } } @Override public void remConnectionListener(IConnectionListener listener) { if (connection != null) { connection.remConnectionListener(listener); } } @Override public int getRating() { return rating; } @Override public boolean isConnected() { return getState(PeerState.class) == PeerState.OKAY; } @Override public String toString() { return "CPeer{" + "Uri=" + uri + "; State=" + (fsm != null ? fsm.getState(PeerState.class) : "n/a") + "; Con=" + connection + "}"; } protected void fillIPAddressTable(IMessage message) { AvpSet avps = message.getAvps().getAvps(HOST_IP_ADDRESS); if (avps != null) { ArrayList t = new ArrayList(); for (int i = 0; i < avps.size(); i++) { try { t.add(avps.getAvpByIndex(i).getAddress()); } catch (AvpDataException e) { logger.warn("Unable to retrieve IP Address from Host-IP-Address AVP"); } } addresses = t.toArray(new InetAddress[t.size()]); } } protected Set getCommonApplicationIds(IMessage message) { //TODO: fix this, its not correct lookup. It should check realm! //it does not include application Ids for which listeners register - and on this basis it consume message! Set newAppId = new HashSet(); Set locAppId = metaData.getLocalPeer().getCommonApplications(); List remAppId = message.getApplicationIdAvps(); logger.debug("Checking common applications. Remote applications: {}. Local applications: {}", remAppId, locAppId); // check common application for (ApplicationId l : locAppId) { for (ApplicationId r : remAppId) { if (l.equals(r)) { newAppId.add(l); } else if (r.getAcctAppId() == INT_COMMON_APP_ID || r.getAuthAppId() == INT_COMMON_APP_ID || l.getAcctAppId() == INT_COMMON_APP_ID || l.getAuthAppId() == INT_COMMON_APP_ID) { newAppId.add(r); } } } return newAppId; } protected void sendErrorAnswer(IRequest request, String errorMessage, int resultCode, Avp... avpsToAdd) { logger.debug("Could not process request. Result Code = [{}], Error Message: [{}]", resultCode, errorMessage); request.setRequest(false); // Not setting error flag, depends on error code. Will be set @ PeerImpl.ActionContext.sendMessage(IMessage) // request.setError(true); request.getAvps().addAvp(RESULT_CODE, resultCode, true, false, true); //add before removal actions if (avpsToAdd != null) { for (Avp a : avpsToAdd) { request.getAvps().addAvp(a); } } request.getAvps().removeAvp(ORIGIN_HOST); request.getAvps().removeAvp(ORIGIN_REALM); request.getAvps().addAvp(ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); request.getAvps().addAvp(ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); if (errorMessage != null) { request.getAvps().addAvp(ERROR_MESSAGE, errorMessage, false); } // Remove trash avp request.getAvps().removeAvp(DESTINATION_HOST); request.getAvps().removeAvp(DESTINATION_REALM); try { logger.debug("Sending response indicating we could not process request"); sendMessage((IMessage) request); if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.SysGenResponse.name()).inc(); } } catch (Exception e) { logger.debug("Unable to send answer", e); } if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.NetGenRejectedRequest.name()).inc(); } } protected class ActionContext implements IContext { @Override public String toString() { return new StringBuilder("ActionContext [getPeerDescription()=").append(getPeerDescription()) .append(", isConnected()=").append(isConnected()).append(", isRestoreConnection()=") .append(isRestoreConnection()).append("]").toString(); } @Override public void connect() throws InternalException, IOException, IllegalDiameterStateException { try { connection.connect(); if (logger.isDebugEnabled()) { logger.debug("Connected to peer {}", getUri()); } } catch (TransportException e) { logger.debug("Failure establishing connection.", e); switch (e.getCode()) { case NetWorkError: throw new IOException("Unable to connect to " + connection.getKey() + " - " + e.getMessage()); case FailedSendMessage: throw new IllegalDiameterStateException(e); default: throw new InternalException(e); } } } @Override public void disconnect() throws InternalException, IllegalDiameterStateException { if (connection != null) { connection.disconnect(); if (logger.isDebugEnabled()) { logger.debug("Disconnected from peer {}", getUri()); } } } @Override public String getPeerDescription() { return uri.toString(); } @Override public boolean isConnected() { return (connection != null) && connection.isConnected(); } @Override public boolean sendMessage(IMessage message) throws TransportException, OverloadException { // Check message if (message.isTimeOut()) { logger.debug("Message {} skipped (timeout)", message); return false; } if (message.getState() == IMessage.STATE_SENT) { logger.debug("Message {} already sent", message); return false; } // Remove destination information from answer messages if (!message.isRequest()) { try { long resultCode = message.getResultCode().getUnsigned32(); message.setError(resultCode >= 3000 && resultCode < 4000); } catch (Exception e) { logger.debug("Unable to retrieve Result-Code from answer. Not setting ERROR bit."); // ignore. should not happen } // 6.2. Diameter Answer Processing answers and Error messages DONT have those.... pffff. message.getAvps().removeAvp(DESTINATION_HOST); message.getAvps().removeAvp(DESTINATION_REALM); int commandCode = message.getCommandCode(); // We don't want this for CEx/DWx/DPx if (commandCode != 257 && commandCode != 280 && commandCode != 282) { if (table instanceof MutablePeerTableImpl) { // available only to server, client skip this step MutablePeerTableImpl peerTable = (MutablePeerTableImpl) table; if (peerTable.isDuplicateProtection()) { String[] originInfo = router.getRequestRouteInfo(message); if (originInfo != null) { // message.getDuplicationKey() doesn't work because it's answer peerTable.saveToDuplicate( message.getDuplicationKey(originInfo[0], message.getEndToEndIdentifier()), message); } } } } } // PCB added this router.garbageCollectRequestRouteInfo(message); // Send to network message.setState(IMessage.STATE_SENT); logger.debug("Calling connection to send message [{}] to peer [{}] over the network", message, getUri()); connection.sendMessage(message); logger.debug("Connection sent message [{}] to peer [{}] over the network", message, getUri()); return true; } @Override public void sendCerMessage() throws TransportException, OverloadException { logger.debug("Send CER message"); IMessage message = parser.createEmptyMessage(CAPABILITIES_EXCHANGE_REQUEST, 0); message.setRequest(true); message.setHopByHopIdentifier(getHopByHopIdentifier()); if (useUriAsFQDN) { message.getAvps().addAvp(ORIGIN_HOST, metaData.getLocalPeer().getUri().toString(), true, false, true); } else { message.getAvps().addAvp(ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); } message.getAvps().addAvp(ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); for (InetAddress ia : metaData.getLocalPeer().getIPAddresses()) { message.getAvps().addAvp(HOST_IP_ADDRESS, ia, true, false); } message.getAvps().addAvp(VENDOR_ID, metaData.getLocalPeer().getVendorId(), true, false, true); message.getAvps().addAvp(PRODUCT_NAME, metaData.getLocalPeer().getProductName(), false); for (ApplicationId appId : metaData.getLocalPeer().getCommonApplications()) { addAppId(appId, message); } message.getAvps().addAvp(FIRMWARE_REVISION, metaData.getLocalPeer().getFirmware(), true); message.getAvps().addAvp(ORIGIN_STATE_ID, metaData.getLocalHostStateId(), true, false, true); sendMessage(message); } @Override public void sendCeaMessage(int resultCode, Message cer, String errMessage) throws TransportException, OverloadException { } @Override public void sendDwrMessage() throws TransportException, OverloadException { logger.debug("Send DWR message"); IMessage message = parser.createEmptyMessage(DEVICE_WATCHDOG_REQUEST, 0); message.setRequest(true); message.setHopByHopIdentifier(getHopByHopIdentifier()); // Set content message.getAvps().addAvp(ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); message.getAvps().addAvp(ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); message.getAvps().addAvp(ORIGIN_STATE_ID, metaData.getLocalHostStateId(), true, false, true); // Remove trash avp message.getAvps().removeAvp(DESTINATION_HOST); message.getAvps().removeAvp(DESTINATION_REALM); // Send sendMessage(message); } @Override public void sendDwaMessage(IMessage dwr, int resultCode, String errorMessage) throws TransportException, OverloadException { logger.debug("Send DWA message"); IMessage message = parser.createEmptyMessage(dwr); message.setRequest(false); message.setHopByHopIdentifier(dwr.getHopByHopIdentifier()); message.setEndToEndIdentifier(dwr.getEndToEndIdentifier()); // Set content message.getAvps().addAvp(RESULT_CODE, resultCode, true, false, true); message.getAvps().addAvp(ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); message.getAvps().addAvp(ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); if (errorMessage != null) { message.getAvps().addAvp(ERROR_MESSAGE, errorMessage, false); } // Remove trash avp message.getAvps().removeAvp(DESTINATION_HOST); message.getAvps().removeAvp(DESTINATION_REALM); // Send sendMessage(message); } @Override public boolean isRestoreConnection() { return true; } @Override public void sendDprMessage(int disconnectCause) throws TransportException, OverloadException { logger.debug("Send DPR message with Disconnect-Cause [{}]", disconnectCause); IMessage message = parser.createEmptyMessage(DISCONNECT_PEER_REQUEST, 0); message.setRequest(true); message.setHopByHopIdentifier(getHopByHopIdentifier()); message.getAvps().addAvp(ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); message.getAvps().addAvp(ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); message.getAvps().addAvp(DISCONNECT_CAUSE, disconnectCause, true, false); sendMessage(message); } @Override public void sendDpaMessage(IMessage dpr, int resultCode, String errorMessage) throws TransportException, OverloadException { logger.debug("Send DPA message"); IMessage message = parser.createEmptyMessage(dpr); message.setRequest(false); message.setHopByHopIdentifier(dpr.getHopByHopIdentifier()); message.setEndToEndIdentifier(dpr.getEndToEndIdentifier()); message.getAvps().addAvp(RESULT_CODE, resultCode, true, false, true); message.getAvps().addAvp(ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); message.getAvps().addAvp(ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); if (errorMessage != null) { message.getAvps().addAvp(ERROR_MESSAGE, errorMessage, false); } sendMessage(message); } @Override public int processCerMessage(String key, IMessage message) { return 0; } @Override public boolean processCeaMessage(String key, IMessage message) { boolean rc = true; try { Avp origHost = message.getAvps().getAvp(ORIGIN_HOST); Avp origRealm = message.getAvps().getAvp(ORIGIN_REALM); Avp vendorId = message.getAvps().getAvp(VENDOR_ID); Avp prdName = message.getAvps().getAvp(PRODUCT_NAME); Avp resCode = message.getAvps().getAvp(RESULT_CODE); Avp frmId = message.getAvps().getAvp(FIRMWARE_REVISION); if (origHost == null || origRealm == null || vendorId == null) { logger.warn("Incorrect CEA message (missing mandatory AVPs)"); } else { if (realmName == null) { realmName = origRealm.getDiameterIdentity(); } if (vendorID == 0) { vendorID = vendorId.getUnsigned32(); } fillIPAddressTable(message); if (productName == null && prdName != null) { productName = prdName.getUTF8String(); } if (resCode != null) { int mrc = resCode.getInteger32(); if (mrc != ResultCode.SUCCESS) { logger.debug("Result code value {}", mrc); return false; } } Set cai = getCommonApplicationIds(message); if (cai.size() > 0) { commonApplications.clear(); commonApplications.addAll(cai); } else { logger.debug("CEA did not contained appId, therefore set local appids to common-appid field"); commonApplications.clear(); commonApplications.addAll(metaData.getLocalPeer().getCommonApplications()); } if (firmWare == 0 && frmId != null) { firmWare = frmId.getInteger32(); } } } catch (Exception exc) { logger.debug("Incorrect CEA message", exc); rc = false; } return rc; } @Override public boolean receiveMessage(IMessage message) { logger.debug("Receiving message in client."); boolean isProcessed = false; // TODO: this might not be proper, since there might be no session // present in case of stateless traffic if (message.isRequest()) { logger.debug("Message is a request"); // checks in server side make sure we are legit, now lets check if there is session present String avpSessionId = message.getSessionId(); if (avpSessionId != null) { // XXX: FT/HA // NetworkReqListener listener = slc.get(avpSessionId); NetworkReqListener listener = sessionDataSource.getSessionListener(avpSessionId); if (listener != null) { router.registerRequestRouteInfo(message); IMessage answer = (IMessage) listener.processRequest(message); if (answer != null) { try { sendMessage(answer); if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.AppGenResponse.name()).inc(); } } catch (Exception e) { logger.warn("Unable to send immediate answer {}", answer); } } if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.NetGenRequest.name()).inc(); } isProcessed = true; } else { if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.NetGenRejectedRequest.name()).inc(); } } } } else { logger.debug("Message is an answer"); //TODO: check REALMs here? IMessage request = peerRequests.remove(message.getHopByHopIdentifier()); if (request != null && !request.isTimeOut()) { request.clearTimer(); request.setState(IMessage.STATE_ANSWERED); Avp avpResCode = message.getAvps().getAvp(RESULT_CODE); if (isRedirectAnswer(avpResCode, message)) { message.setListener(request.getEventListener()); message = processRedirectAnswer(request, message); //if return value is not null, there was some error, lets try to invoke listener if it exists... isProcessed = message == null; } if (message != null) { if (request.getEventListener() != null) { request.getEventListener().receivedSuccessMessage(request, message); } else { logger.debug("Unable to call answer listener for request {} because listener is not set", message); if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.NetGenRejectedResponse.name()).inc(); } } isProcessed = true; if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.NetGenResponse.name()).inc(); } } else { if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.NetGenRejectedResponse.name()).inc(); } } } else { if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.NetGenRejectedResponse.name()).inc(); } } } return isProcessed; } @Override public int processDwrMessage(IMessage iMessage) { return ResultCode.SUCCESS; } @Override public int processDprMessage(IMessage iMessage) { return ResultCode.SUCCESS; } protected void addAppId(ApplicationId appId, IMessage message) { if (appId.getVendorId() == 0) { if (appId.getAuthAppId() != 0) { message.getAvps().addAvp(AUTH_APPLICATION_ID, appId.getAuthAppId(), true, false, true); } else if (appId.getAcctAppId() != 0) { message.getAvps().addAvp(ACCT_APPLICATION_ID, appId.getAcctAppId(), true, false, true); } } else { // Avoid duplicates boolean vendorIdPresent = false; for (Avp avp : message.getAvps().getAvps(SUPPORTED_VENDOR_ID)) { try { if (avp.getUnsigned32() == appId.getVendorId()) { vendorIdPresent = true; break; } } catch (Exception e) { logger.debug("Failed to read Supported-Vendor-Id.", e); } } if (!vendorIdPresent) { message.getAvps().addAvp(SUPPORTED_VENDOR_ID, appId.getVendorId(), true, false, true); } AvpSet vendorApp = message.getAvps().addGroupedAvp(VENDOR_SPECIFIC_APPLICATION_ID, true, false); vendorApp.addAvp(VENDOR_ID, appId.getVendorId(), true, false, true); if (appId.getAuthAppId() != 0) { vendorApp.addAvp(AUTH_APPLICATION_ID, appId.getAuthAppId(), true, false, true); } if (appId.getAcctAppId() != 0) { vendorApp.addAvp(ACCT_APPLICATION_ID, appId.getAcctAppId(), true, false, true); } } } /* * (non-Javadoc) * * @see org.jdiameter.client.api.fsm.IContext#removePeerStatistics() */ @Override public void removeStatistics() { removePeerStatistics(); } /* * (non-Javadoc) * * @see org.jdiameter.client.api.fsm.IContext#createPeerStatistics() */ @Override public void createStatistics() { createPeerStatistics(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerTableImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.controller; import static org.jdiameter.client.impl.helpers.Parameters.*; import java.io.IOException; import java.net.URISyntaxException; import java.net.UnknownServiceException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.atomic.AtomicLong; import org.jdiameter.api.*; import org.jdiameter.api.validation.AvpNotAllowedException; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.client.api.IAssembler; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IMetaData; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.controller.IPeerTable; import org.jdiameter.client.api.fsm.IFsmFactory; import org.jdiameter.client.api.io.ITransportLayerFactory; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.router.IRouter; import org.jdiameter.client.impl.DictionarySingleton; import org.jdiameter.client.impl.helpers.Parameters; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class PeerTableImpl implements IPeerTable { private static final Logger logger = LoggerFactory.getLogger(PeerTableImpl.class); // Peer table protected ConcurrentHashMap peerTable = new ConcurrentHashMap(); protected boolean isStarted; protected long stopTimeOut; protected IAssembler assembler; protected IRouter router; protected MetaData metaData; protected IConcurrentFactory concurrentFactory; // XXX: FT/HA // protected ConcurrentHashMap sessionReqListeners = new ConcurrentHashMap(); protected ISessionDatasource sessionDatasource; protected final Dictionary dictionary = DictionarySingleton.getDictionary(); protected PeerTableImpl() { } public PeerTableImpl(Configuration globalConfig, MetaData metaData, IContainer stack, IRouter router, IFsmFactory fsmFactory, ITransportLayerFactory transportFactory, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, IMessageParser parser) { init(stack, router, globalConfig, metaData, fsmFactory, transportFactory, statisticFactory, concurrentFactory, parser); } protected void init(IContainer stack, IRouter router, Configuration globalConfig, MetaData metaData, IFsmFactory fsmFactory, ITransportLayerFactory transportFactory, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, IMessageParser parser) { logger.debug("Initializing Peer Table."); this.router = router; this.metaData = metaData; this.concurrentFactory = concurrentFactory; this.stopTimeOut = globalConfig.getLongValue(StopTimeOut.ordinal(), (Long) StopTimeOut.defValue()); this.sessionDatasource = stack.getAssemblerFacility().getComponentInstance(ISessionDatasource.class); logger.debug("Populating peerTable from configuration"); Configuration[] peers = globalConfig.getChildren(Parameters.PeerTable.ordinal()); if (peers != null && peers.length > 0) { for (Configuration peerConfig : peers) { if (peerConfig.isAttributeExist(PeerName.ordinal())) { String uri = peerConfig.getStringValue(PeerName.ordinal(), null); int rating = peerConfig.getIntValue(PeerRating.ordinal(), 0); String ip = peerConfig.getStringValue(PeerIp.ordinal(), null); String portRange = peerConfig.getStringValue(PeerLocalPortRange.ordinal(), null); try { // create predefined peer IPeer peer = (IPeer) createPeer(rating, uri, ip, portRange, metaData, globalConfig, peerConfig, fsmFactory, transportFactory, statisticFactory, concurrentFactory, parser); if (peer != null) { //NOTE: this depends on conf, in normal case realm is younger part of FQDN, but in some cases //conf peers may contain IPs only... sucks. peer.setRealm(router.getRealmTable().getRealmForPeer(peer.getUri().getFQDN())); peerTable.put(peer.getUri().getFQDN(), peer); logger.debug("Appended peer [{}] to peer table", peer); } } catch (Exception e) { logger.warn("Unable to create peer [" + uri + "]", e); } } } } } protected Peer createPeer(int rating, String uri, String ip, String portRange, MetaData metaData, Configuration config, Configuration peerConfig, IFsmFactory fsmFactory, ITransportLayerFactory transportFactory, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, IMessageParser parser) throws InternalException, TransportException, URISyntaxException, UnknownServiceException { return new PeerImpl(this, rating, new URI(uri), ip, portRange, metaData.unwrap(IMetaData.class), config, peerConfig, fsmFactory, transportFactory, statisticFactory, concurrentFactory, parser, this.sessionDatasource); } @Override public List getPeerTable() { return new ArrayList(peerTable.values()); } @Override public void sendMessage(IMessage message) throws IllegalDiameterStateException, RouteException, AvpDataException, IOException { if (!isStarted) { throw new IllegalDiameterStateException("Stack is down"); } // Get context IPeer peer; if (message.isRequest()) { if (logger.isDebugEnabled()) { logger.debug("Send request {} [destHost={}; destRealm={}]", new Object[] { message, message.getAvps().getAvp(Avp.DESTINATION_HOST) != null ? message.getAvps().getAvp(Avp.DESTINATION_HOST).getOctetString() : "", message.getAvps().getAvp(Avp.DESTINATION_REALM) != null ? message.getAvps().getAvp(Avp.DESTINATION_REALM).getOctetString() : "" }); } // Check local request if (router.updateRoute(message)) { if (logger.isDebugEnabled()) { logger.debug("Updated route on message {} [destHost={}; destRealm={}]", new Object[] { message, message.getAvps().getAvp(Avp.DESTINATION_HOST) != null ? message.getAvps().getAvp(Avp.DESTINATION_HOST).getOctetString() : "", message.getAvps().getAvp(Avp.DESTINATION_REALM) != null ? message.getAvps().getAvp(Avp.DESTINATION_REALM).getOctetString() : "" }); } } peer = router.getPeer(message, this); logger.debug("Selected peer [{}] for sending message [{}]", peer, message); if (peer == metaData.getLocalPeer()) { logger.debug("Request [{}] will be processed by local service", message); } else { message.setHopByHopIdentifier(peer.getHopByHopIdentifier()); peer.addMessage(message); message.setPeer(peer); } } else { logger.debug("Message is an answer"); peer = message.getPeer(); if (peer == null) { logger.debug("Peer is null so we will use router.getPeer to find a peer"); peer = router.getPeer(message, this); if (peer == null) { throw new RouteException("Cannot found remote context for sending message"); } logger.debug("Found a peer [{}] and setting it as the peer in the message", peer); message.setPeer(peer); } } try { logger.debug("Calling sendMessage on peer [{}]", peer); if (!peer.sendMessage(message)) { throw new IOException("Can not send message"); } else { logger.debug("Message was submitted to be sent, now adding statistics"); if (message.isRequest()) { if (peer.getStatistic().isEnabled()) { peer.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRequest.name()).inc(); } } else { if (peer.getStatistic().isEnabled()) { peer.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenResponse.name()).inc(); } } } } catch (Exception e) { logger.error("Can not send message", e); if (message.isRequest()) { if (peer.getStatistic().isEnabled()) { peer.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRejectedRequest.name()).inc(); } } else { if (peer.getStatistic().isEnabled()) { peer.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRejectedResponse.name()).inc(); } } if (e instanceof AvpNotAllowedException) { throw (AvpNotAllowedException) e; } else { throw new IOException(e.getMessage()); } } } @Override public void addSessionReqListener(String sessionId, NetworkReqListener listener) { // XXX: FT/HA // sessionReqListeners.put(sessionId, listener); logger.debug("Adding sessionId [{}] to sessionDatasource", sessionId); sessionDatasource.setSessionListener(sessionId, listener); } @Override public Map getSessionReqListeners() { // XXX: FT/HA // return sessionReqListeners; return null; } @Override public IPeer getPeer(String fqdn) { logger.debug("In getPeer for peer with FQDN [{}]. Going to find a matching entry in peerTable", fqdn); IPeer peer = (IPeer) peerTable.get(fqdn); if (peer == null) { logger.debug("No peer found in getPeer for peer [{}] will return null", fqdn); return null; } logger.debug("Found matching peer [{}]. Is connection open ? {}.", peer.getUri(), peer.hasValidConnection()); return peer; } @Override public void removeSessionListener(String sessionId) { // XXX: FT/HA // sessionReqListeners.remove(sessionId); sessionDatasource.removeSessionListener(sessionId); } @Override public void setAssembler(IAssembler assembler) { this.assembler = assembler; } // Life cycle @Override public void start() throws IllegalDiameterStateException, IOException { logger.debug("Starting PeerTable. Going to call connect on all peers in the peerTable"); for (Peer peer : peerTable.values()) { try { peer.connect(); } catch (Exception e) { logger.warn("Can not start connect procedure to peer [" + peer + "]", e); } } logger.debug("Calling start on the router"); router.start(); isStarted = true; } @Override public void stopped() { logger.debug("Calling stopped() on PeerTableImpl"); // XXX: FT/HA // if (sessionReqListeners != null) { // XXX: FT/HA // sessionReqListeners.clear(); // XXX: FT/HA // } for (Peer p : peerTable.values()) { for (IMessage m : ((IPeer) p).remAllMessage()) { try { m.runTimer(); } catch (Exception e) { logger.debug("Unable to stop timer on message", e); } } } if (concurrentFactory != null) { try { // Wait for some threads which may take longer... // FIXME: Change this once we get rid of ThreadGroup and hard interrupting threads. // boolean interrupted = false; long remWaitTime = 2000; logger.debug("Stopping thread group and waiting a max of {}ms for all threads to finish", remWaitTime); while (((ThreadPoolExecutor) concurrentFactory.getThreadPool()).getActiveCount() > 0 && remWaitTime > 0) { long waitTime = 250; Thread.sleep(waitTime); remWaitTime -= waitTime; logger.debug("Waited {}ms. Time remaining to wait: {}ms. {} Thread still active.", new Object[] { waitTime, remWaitTime, ((ThreadPoolExecutor) concurrentFactory.getThreadPool()).getActiveCount() }); // it did not terminated, let's interrupt // FIXME: remove ASAP, this is very bad, it kills threads in middle of op, // killing FSM of peer for instance, after that its not usable. // if (remWaitTime <= 0 && !interrupted) { // interrupted = true; // remWaitTime = 2000; // logger.debug("Stopping thread group did not work. Interrupting and waiting a max of {}ms for all threads to finish", remWaitTime); // concurrentFactory.getThreadGroup().interrupt(); // } } } catch (Exception e) { logger.warn("Unable to stop executor"); } } router.stop(); } @Override public void stopping(int disconnectCause) { logger.debug("In stopping. Going to disconnect all peers in peer table"); isStarted = false; for (Peer peer : peerTable.values()) { try { peer.disconnect(disconnectCause); } catch (Exception e) { logger.warn("Failure disconnecting peer [" + peer.getUri().toString() + "]", e); } } } @Override public void destroy() { logger.debug("In destroy. Going to destroy concurrentFactory's thread group"); if (router != null) { logger.debug("Calling destroy on router"); router.destroy(); } router = null; peerTable = null; assembler = null; } // Extension interface @Override public boolean isWrapperFor(Class aClass) throws InternalException { return false; } @Override public T unwrap(Class aClass) throws InternalException { return null; } protected class PeerTableThreadFactory { public final AtomicLong sequence = new AtomicLong(0); private int priority = Thread.NORM_PRIORITY; private ExecutorService threadPoolExecutor = Executors.newCachedThreadPool(); public PeerTableThreadFactory(int priority) { super(); this.priority = priority; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/RealmImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.controller; import java.util.Arrays; import java.util.Collection; import java.util.concurrent.ConcurrentLinkedQueue; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.LocalAction; import org.jdiameter.client.api.controller.IRealm; import org.jdiameter.server.api.agent.IAgent; import org.jdiameter.server.api.agent.IAgentConfiguration; /** * The Realm class implements rows in the Diameter Realm routing table. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RealmImpl implements IRealm { protected String name; protected ApplicationId appId; protected LocalAction action; protected boolean dynamic; protected long expirationTime; protected Collection hosts = new ConcurrentLinkedQueue(); protected IAgent agent; protected IAgentConfiguration agentConfiguration; public RealmImpl(String name, ApplicationId applicationId, LocalAction localAction, IAgent agent, IAgentConfiguration agentConfiguration, boolean dynamic, long expirationTime, String... hosts) { this.hosts.addAll(Arrays.asList(hosts)); this.name = name; this.appId = applicationId; this.action = localAction; this.dynamic = dynamic; this.expirationTime = expirationTime; this.agent = agent; this.agentConfiguration = agentConfiguration; } /** * Return name of this realm * * @return name */ @Override public String getName() { return name; } /** * Return applicationId associated with this realm * * @return applicationId */ @Override public ApplicationId getApplicationId() { return appId; } /** * Return realm local action for this realm * * @return realm local action */ @Override public LocalAction getLocalAction() { return action; } /** * Return list of real peers * * @return array of realm peers */ @Override public String[] getPeerNames() { return hosts.toArray(new String[hosts.size()]); } /** * Append new host (peer) to this realm * * @param host name of peer host */ @Override public void addPeerName(String name) { if (!hasPeerName(name)) { hosts.add(name); } } /** * Remove peer from this realm * * @param host name of peer host */ @Override public void removePeerName(String s) { hosts.remove(name); } /** * Return true if this realm is dynamic updated * * @return true if this realm is dynamic updated */ @Override public boolean isDynamic() { return dynamic; } /** * Return expiration time for this realm in milisec * * @return expiration time */ @Override public long getExpirationTime() { return expirationTime; } @Override public boolean hasPeerName(String name) { return this.hosts.contains(name); } @Override public IAgent getAgent() { return agent; } @Override public IAgentConfiguration getAgentConfiguration() { return this.agentConfiguration; } @Override public boolean isLocal() { return false; } @Override public String toString() { return "RealmImpl [name=" + name + ", appId=" + appId + ", action=" + action + ", dynamic=" + dynamic + ", expirationTime=" + expirationTime + ", hosts=" + hosts + ", agent=" + agent + "]"; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/RealmTableImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.controller; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.InternalException; import org.jdiameter.api.LocalAction; import org.jdiameter.api.Realm; import org.jdiameter.api.Statistic; import org.jdiameter.client.api.IAnswer; import org.jdiameter.client.api.IAssembler; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.controller.IRealm; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.server.api.agent.IAgent; import org.jdiameter.server.api.agent.IAgentConfiguration; import org.jdiameter.server.api.agent.IProxy; import org.jdiameter.server.api.agent.IRedirect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RealmTableImpl implements IRealmTable { private static final Logger logger = LoggerFactory.getLogger(RealmTableImpl.class); // maps name->realms (cause there might be more than one realm defined, with different app id. protected Map realmNameToRealmSet = new HashMap(); // "cache" so we don't have to combine all realms protected List allRealmsSet = new ArrayList(); protected String localRealmName; protected String localHost; protected IAssembler assembler; public RealmTableImpl(IContainer con) { this.assembler = con.getAssemblerFacility(); } @Override public boolean realmExists(String realmName) { // NOTE: this is still valid for local realm return (this.realmNameToRealmSet.containsKey(realmName) && this.realmNameToRealmSet.get(realmName).size() > 0); } @Override public Realm addRealm(String realmName, ApplicationId applicationId, LocalAction action, String agentConfiguration, boolean dynamic, long expirationTime, String[] hosts) throws InternalException { logger.debug("Adding realm [{}] into network map", realmName); IAgentConfiguration agentConf = this.assembler.getComponentInstance(IAgentConfiguration.class); if (agentConf != null) { agentConf = agentConf.parse(agentConfiguration); } return addRealm(realmName, applicationId, action, agentConf, dynamic, expirationTime, hosts); } @Override public Realm addRealm(String realmName, ApplicationId applicationId, LocalAction action, IAgentConfiguration agentConf, boolean dynamic, long expirationTime, String[] hosts) throws InternalException { IAgent agent = null; switch (action) { case LOCAL: case RELAY: break; case PROXY: agent = this.assembler.getComponentInstance(IProxy.class); break; case REDIRECT: agent = this.assembler.getComponentInstance(IRedirect.class); break; } RealmImpl realmImpl = new RealmImpl(realmName, applicationId, action, agent, agentConf, dynamic, expirationTime, hosts); addRealm(realmImpl); return realmImpl; } /* * (non-Javadoc) * * @see org.jdiameter.client.api.controller.IRealmTable#getRealm(java.lang.String, org.jdiameter.api.ApplicationId) */ @Override public Realm getRealm(String realmName, ApplicationId applicationId) { RealmSet rs = this.realmNameToRealmSet.get(realmName); return rs == null ? null : rs.getRealm(applicationId); } /* * (non-Javadoc) * * @see org.jdiameter.client.api.controller.IRealmTable#removeRealmApplicationId(java.lang.String, * org.jdiameter.api.ApplicationId) */ @Override public Realm removeRealmApplicationId(String realmName, ApplicationId appId) { RealmSet set = this.realmNameToRealmSet.get(realmName); if (set != null) { Realm r = set.getRealm(appId); set.removeRealm(appId); if (set.size() == 0 && !realmName.equals(this.localRealmName)) { this.realmNameToRealmSet.remove(realmName); this.allRealmsSet.remove(realmName); } return r; } return null; } /* * (non-Javadoc) * * @see org.jdiameter.client.api.controller.IRealmTable#removeRealms(java.lang.String) */ @Override public Collection removeRealm(String realmName) { RealmSet set = null; if (realmName.equals(this.localRealmName)) { set = this.realmNameToRealmSet.get(realmName); } else { set = this.realmNameToRealmSet.remove(realmName); if (set != null) { Collection present = set.values(); allRealmsSet.remove(realmName); return new ArrayList(present); } } return null; } /* * (non-Javadoc) * * @see org.jdiameter.client.api.controller.IRealmTable#getRealms(java.lang.String) */ @Override public Collection getRealms(String realmName) { RealmSet set = this.realmNameToRealmSet.get(realmName); if (set != null) { Collection present = set.values(); return new ArrayList(present); } return new ArrayList(0); } /* * (non-Javadoc) * * @see org.jdiameter.client.api.controller.IRealmTable#getRealms() */ @Override public Collection getRealms() { ArrayList rss = new ArrayList(); Set keys = new HashSet(this.realmNameToRealmSet.keySet()); for (String key : keys) { RealmSet rs = this.realmNameToRealmSet.get(key); rss.addAll(rs.values()); } return rss; } /* * (non-Javadoc) * * @see org.jdiameter.client.api.controller.IRealmTable#matchRealm(org.jdiameter.client.api.IRequest) */ @Override public Realm matchRealm(IRequest request) { try { // once again casting... IMessage req = (IMessage) request; String destinationRealm = req.getAvps().getAvp(Avp.DESTINATION_REALM).getDiameterIdentity(); // we have req, we need match, not dummy longest from right BS match. return this.matchRealm(req, destinationRealm); } catch (Exception e) { logger.error("Unable to read Destination-Realm AVP to match realm to request", e); } return null; } /* * (non-Javadoc) * * @see org.jdiameter.client.api.controller.IRealmTable#matchRealm(org.jdiameter.client.api.IAnswer, java.lang.String) */ @Override public Realm matchRealm(IAnswer message, String destRealm) { return this.matchRealm((IMessage) message, destRealm); } /* * (non-Javadoc) * * @see org.jdiameter.client.api.controller.IRealmTable#getRealmForPeer(java.lang.String) */ @Override public String getRealmForPeer(String fqdn) { // Collection realms = getRealms(); for (Realm r : realms) { IRealm ir = (IRealm) r; if (ir.hasPeerName(fqdn)) { return ir.getName(); } } return null; } /** * @param appId */ @Override public void addLocalApplicationId(ApplicationId appId) { RealmSet rs = getRealmSet(localRealmName, false); rs.addRealm(new RealmImpl(localRealmName, appId, LocalAction.LOCAL, null, null, true, -1, this.localHost) { @Override public boolean isLocal() { return true; } }); } /** * @param appId */ @Override public void removeLocalApplicationId(ApplicationId appId) { RealmSet rs = getRealmSet(localRealmName, false); Realm realm = rs.getRealm(appId); if (realm.isDynamic()) { rs.removeRealm(appId); } } /** * @param localRealm * @param fqdn */ @Override public void addLocalRealm(String localRealm, String fqdn) { this.localRealmName = localRealm; this.localHost = fqdn; getRealmSet(localRealm, true /* adds realm if not present */); } // -------------------- helper methods -------------------- protected Realm matchRealm(IMessage message, String realm) { if (realmExists(realm)) { ApplicationId singleId = message.getSingleApplicationId(); // check on single app id, than we iterate. Realm r = getRealm(realm, singleId); if (r == null) { List appIds = message.getApplicationIdAvps(); for (int index = 0; index < appIds.size(); index++) { r = getRealm(realm, appIds.get(index)); if (r != null) { break; } } } return r; } return null; } protected void addRealm(Realm realm) throws InternalException { RealmSet rs = getRealmSet(realm.getName(), true); rs.addRealm(realm); allRealmsSet.add(realm.getName()); } protected RealmSet getRealmSet(String pKey, boolean create) { RealmSet rs = realmNameToRealmSet.get(pKey); if (rs == null && create) { rs = new RealmSet(); realmNameToRealmSet.put(pKey, rs); } return rs; } private class RealmSet { // TODO: use two lists and iterate over index? protected Map appIdToRealm = new HashMap(); /** * @param realm * * @throws InternalException */ public void addRealm(Realm realm) { if (this.appIdToRealm.containsKey(realm.getApplicationId())) { Realm presentRealm = this.appIdToRealm.get(realm.getApplicationId()); if (realm.getName().equals(localRealmName)) { // we need to merge - its a local realm, possibly definition // of hosts that can handle requests for us. RealmImpl realmImpl = (RealmImpl) presentRealm; realmImpl.dynamic = false; // ensure its static for (String peerName : ((RealmImpl) realm).getPeerNames()) { realmImpl.addPeerName(peerName); } } else if (!presentRealm.isDynamic() && realm.isDynamic()) { // its a dynamic realm, present is static, we dont have to // do a thing? } else if (presentRealm.isDynamic() && !realm.isDynamic()) { // we need to merge? RealmImpl realmImpl = (RealmImpl) presentRealm; realmImpl.dynamic = false; // make it static :) for (String peerName : ((RealmImpl) realm).getPeerNames()) { realmImpl.addPeerName(peerName); } } else { if (logger.isDebugEnabled()) { logger.debug("Entry for realm '{}', already exists: {}", realm, this); } } } else { this.appIdToRealm.put(realm.getApplicationId(), realm); } } /** * @return */ public Collection values() { return this.appIdToRealm.values(); } /** * @return */ public int size() { return this.appIdToRealm.size(); } /** * @param appId * * @return */ public Realm getRealm(ApplicationId appId) { return this.appIdToRealm.get(appId); } /** * @param appId * * @return */ public Realm removeRealm(ApplicationId appId) { return this.appIdToRealm.remove(appId); } } /* * (non-Javadoc) * * @see org.jdiameter.api.RealmTable#getStatistic(java.lang.String) */ @Override public Statistic getStatistic(String realmName) { // FIXME: ... return null; } /* * (non-Javadoc) * * @see org.jdiameter.api.Wrapper#isWrapperFor(java.lang.Class) */ @Override public boolean isWrapperFor(Class iface) throws InternalException { return false; } /* * (non-Javadoc) * * @see org.jdiameter.api.Wrapper#unwrap(java.lang.Class) */ @Override public T unwrap(Class iface) throws InternalException { return null; } @Override public List getAllRealmSet() { return allRealmsSet; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/fsm/FsmFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.fsm; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.client.api.fsm.IContext; import org.jdiameter.client.api.fsm.IFsmFactory; import org.jdiameter.client.api.fsm.IStateMachine; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.statistic.IStatisticManager; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class FsmFactoryImpl implements IFsmFactory { // TODO: please redesign this code "duplicate" protected IStatisticManager statisticFactory; public FsmFactoryImpl(IStatisticManager statisticFactory) { this.statisticFactory = statisticFactory; } @Override public IStateMachine createInstanceFsm(IContext context, IConcurrentFactory concurrentFactory, Configuration config) throws InternalException { return new org.jdiameter.client.impl.fsm.PeerFSMImpl(context, concurrentFactory, config, statisticFactory); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/fsm/FsmState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.fsm; import org.jdiameter.api.PeerState; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class FsmState { protected static int index; public static FsmState OKAY = new FsmState("OKAY", PeerState.OKAY); public static FsmState SUSPECT = new FsmState("SUSPECT", PeerState.SUSPECT); public static FsmState DOWN = new FsmState("DOWN", PeerState.DOWN); public static FsmState REOPEN = new FsmState("REOPEN", PeerState.REOPEN); public static FsmState INITIAL = new FsmState("INITIAL", PeerState.INITIAL); public static FsmState STOPPING = new FsmState("STOPPING", PeerState.DOWN, true); private String name; private int ordinal; private Enum publicState; private boolean isInternal; public FsmState(String name, Enum publicState) { this.name = name; this.publicState = publicState; this.ordinal = index++; } public FsmState(String name, Enum publicState, boolean isInternal) { this.name = name; this.publicState = publicState; this.isInternal = isInternal; this.ordinal = index++; } public int ordinal() { return ordinal; } public String name() { return name; } public Enum getPublicState() { return publicState; } public boolean isInternal() { return isInternal; } @Override public String toString() { return name; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/fsm/PeerFSMImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.fsm; import static org.jdiameter.client.impl.fsm.FsmState.DOWN; import static org.jdiameter.client.impl.fsm.FsmState.REOPEN; import static org.jdiameter.client.impl.helpers.Parameters.*; import java.util.Random; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.*; import org.jdiameter.api.app.State; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.validation.AvpNotAllowedException; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.fsm.EventTypes; import org.jdiameter.client.api.fsm.FsmEvent; import org.jdiameter.client.api.fsm.IContext; import org.jdiameter.client.api.fsm.IStateMachine; import org.jdiameter.client.impl.DictionarySingleton; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class PeerFSMImpl implements IStateMachine { private static final Logger logger = LoggerFactory.getLogger(PeerFSMImpl.class); protected final Dictionary dictionary = DictionarySingleton.getDictionary(); protected ConcurrentLinkedQueue listeners; protected LinkedBlockingQueue eventQueue; protected FsmState state = FsmState.DOWN; protected boolean watchdogSent; protected long timer; protected long CEA_TIMEOUT = 0, IAC_TIMEOUT = 0, REC_TIMEOUT = 0, DWA_TIMEOUT = 0, DPA_TIMEOUT = 0; //PCB made FSM queue multi-threaded private static int FSM_THREAD_COUNT = 3; protected final StateEvent timeOutEvent = new FsmEvent(EventTypes.TIMEOUT_EVENT); protected Random random = new Random(); protected IConcurrentFactory concurrentFactory; protected IContext context; protected State[] states; protected int predefSize; private Lock lock = new ReentrantLock(); protected IStatisticManager statisticFactory; protected IStatistic queueStat; protected IStatisticRecord timeSumm; protected IStatisticRecord timeCount; //PCB changed for multi-thread protected boolean mustRun = false; protected AtomicInteger numberOfThreadsRunning = new AtomicInteger(0); public PeerFSMImpl(IContext aContext, IConcurrentFactory concurrentFactory, Configuration config, IStatisticManager statisticFactory) { this.context = aContext; this.statisticFactory = statisticFactory; this.predefSize = config.getIntValue(QueueSize.ordinal(), (Integer) QueueSize.defValue()); //PCB added logging logger.debug("Maximum FSM Queue size is [{}]", predefSize); this.eventQueue = new LinkedBlockingQueue(predefSize); this.listeners = new ConcurrentLinkedQueue(); loadTimeOuts(config); this.concurrentFactory = concurrentFactory; FSM_THREAD_COUNT = config.getIntValue(PeerFSMThreadCount.ordinal(), (Integer) PeerFSMThreadCount.defValue()); runQueueProcessing(); } @Override public IStatistic getStatistic() { // return queueStat; } @Override public void removeStateChangeNotification(StateChangeListener stateChangeListener) { listeners.remove(stateChangeListener); } private void runQueueProcessing() { try { // PCB - changed way it decides if queue processing must happen in order to allow for multithreaded FSM lock.lock(); if (numberOfThreadsRunning.get() > 0) { // runQueueProcessing has been called return; } eventQueue.clear(); mustRun = true; IStatisticRecord queueSize = statisticFactory.newCounterRecord(IStatisticRecord.Counters.QueueSize, new IStatisticRecord.IntegerValueHolder() { @Override public int getValueAsInt() { return eventQueue.size(); } @Override public String getValueAsString() { return String.valueOf(getValueAsInt()); } }); this.timeSumm = statisticFactory.newCounterRecord("TimeSumm", "TimeSumm"); this.timeCount = statisticFactory.newCounterRecord("TimeCount", "TimeCount"); final IStatisticRecord messagePrcAverageTime = statisticFactory.newCounterRecord( IStatisticRecord.Counters.MessageProcessingTime, new IStatisticRecord.DoubleValueHolder() { @Override public double getValueAsDouble() { if (queueStat == null) { return 0; } IStatisticRecord mpta = queueStat .getRecordByName(IStatisticRecord.Counters.MessageProcessingTime.name()); org.jdiameter.api.StatisticRecord[] children = mpta.getChilds(); if (children.length == 2 && children[1].getValueAsLong() != 0) { long count = children[1].getValueAsLong(); return ((float) children[0].getValueAsLong()) / ((float) (count != 0 ? count : 1)); } else { return 0; } } @Override public String getValueAsString() { return String.valueOf(getValueAsDouble()); } }, timeSumm, timeCount); logger.debug("Initializing QueueStat @ Thread[{}]", Thread.currentThread().getName()); queueStat = statisticFactory.newStatistic(context.getPeerDescription(), IStatistic.Groups.PeerFSM, queueSize, messagePrcAverageTime); logger.debug("Finished Initializing QueueStat @ Thread[{}]", Thread.currentThread().getName()); Runnable fsmQueueProcessor = new Runnable() { @Override public void run() { int runningNow = numberOfThreadsRunning.incrementAndGet(); logger.debug("Starting ... [{}] FSM threads are running", runningNow); //PCB changed for multi-thread while (mustRun) { StateEvent event; try { event = eventQueue.poll(100, TimeUnit.MILLISECONDS); if (logger.isDebugEnabled() && event != null) { logger.debug("Got Event [{}] from Queue", event); } } catch (InterruptedException e) { logger.debug("Peer FSM stopped", e); break; } //FIXME: baranowb: why this lock is here? // PCB removed lock // lock.lock(); try { if (event != null) { if (event instanceof FsmEvent && queueStat != null && queueStat.isEnabled()) { timeSumm.inc(System.currentTimeMillis() - ((FsmEvent) event).getCreatedTime()); timeCount.inc(); } logger.debug("Process event [{}]. Peer State is [{}]", event, state); getStates()[state.ordinal()].processEvent(event); } if (timer != 0 && timer < System.currentTimeMillis()) { // ZhixiaoLuo: add lock here to avoid 2 timeout events at the same time if 2 threads get into timer=0 // ZhixiaoLuo: use double check strategy to avoid locking most normal cases lock.lock(); try { if (timer != 0 && timer < System.currentTimeMillis()) { timer = 0; if (state != DOWN) { //without this check this event is fired in DOWN state.... it should not be. logger.debug("Sending timeout event"); handleEvent(timeOutEvent); //FIXME: check why timer is not killed? } } } finally { lock.unlock(); } } } catch (Exception e) { logger.debug("Error during processing FSM event", e); } finally { // PCB removed lock // lock.unlock(); } } //PCB added logging logger.debug("FSM Thread {} is exiting", Thread.currentThread().getName()); //this happens when peer FSM is down, lets remove stat statisticFactory.removeStatistic(queueStat); logger.debug("Setting QueueStat to null @ Thread [{}]", Thread.currentThread().getName()); queueStat = null; logger.debug("Done Setting QueueStat to null @ Thread [{}]", Thread.currentThread().getName()); int runningNowAfterStop = numberOfThreadsRunning.decrementAndGet(); logger.debug("Stopping ... [{}] FSM threads are running", runningNowAfterStop); } }; //PCB added FSM multithread for (int i = 1; i <= FSM_THREAD_COUNT; i++) { logger.debug("Starting FSM Thread {} of {}", i, FSM_THREAD_COUNT); concurrentFactory.getThreadPool().execute(fsmQueueProcessor); } } finally { lock.unlock(); } } @Override public double getQueueInfo() { return eventQueue.size() * 1.0 / predefSize; } protected void loadTimeOuts(Configuration config) { CEA_TIMEOUT = config.getLongValue(CeaTimeOut.ordinal(), (Long) CeaTimeOut.defValue()); IAC_TIMEOUT = config.getLongValue(IacTimeOut.ordinal(), (Long) IacTimeOut.defValue()); DWA_TIMEOUT = config.getLongValue(DwaTimeOut.ordinal(), (Long) DwaTimeOut.defValue()); DPA_TIMEOUT = config.getLongValue(DpaTimeOut.ordinal(), (Long) DpaTimeOut.defValue()); REC_TIMEOUT = config.getLongValue(RecTimeOut.ordinal(), (Long) RecTimeOut.defValue()); } @Override public void addStateChangeNotification(StateChangeListener stateChangeListener) { if (!listeners.contains(stateChangeListener)) { listeners.add(stateChangeListener); } } @Override public void remStateChangeNotification(StateChangeListener stateChangeListener) { listeners.remove(stateChangeListener); } protected void switchToNextState(FsmState newState) { // Fix for Issue #3026 (http://code.google.com/p/mobicents/issues/detail?id=3026) // notify only when it's a new public state if (newState.getPublicState() != state.getPublicState()) { for (StateChangeListener l : listeners) { l.stateChanged(state.getPublicState(), newState.getPublicState()); } } getStates()[state.ordinal()].exitAction(); if (logger.isDebugEnabled()) { logger.debug("{} FSM switch state: {} -> {}", new Object[] { context.getPeerDescription(), state, newState }); } state = newState; getStates()[state.ordinal()].entryAction(); } @Override public boolean handleEvent(StateEvent event) throws InternalError, OverloadException { //if (state.getPublicState() == PeerState.DOWN && event.encodeType(EventTypes.class) == EventTypes.START_EVENT) { if (logger.isDebugEnabled()) { logger.debug("Handling event with type [{}]", event.getType()); } //PCB added FSM multithread if (numberOfThreadsRunning.get() == 0) { logger.debug("No FSM threads are running so calling runQueueProcessing()"); runQueueProcessing(); } if (event.getData() != null && dictionary != null && dictionary.isEnabled()) { boolean incoming = event.getType() == EventTypes.RECEIVE_MSG_EVENT; if (incoming) { logger.debug("Performing validation to INCOMING message since validator is ENABLED."); // outgoing are done elsewhere: see BaseSessionImpl try { dictionary.validate((Message) event.getData(), incoming); } catch (AvpNotAllowedException e) { logger.error("Failed to validate incoming message.", e); return false; } } } else { logger.debug("Not performing validation to message since validator is DISABLED."); } boolean rc = false; try { if (logger.isDebugEnabled()) { logger.debug("Placing event [{}] into linked blocking queue with remaining capacity: [{}].", event, eventQueue.remainingCapacity()); //PCB added logging //int queueSize = eventQueue.size(); //if (System.currentTimeMillis() - lastLogged > 1000) { // lastLogged = System.currentTimeMillis(); // if (queueSize >= 5) { // logger.debug("Diameter Event Queue size is [{}]", queueSize); // } //} } rc = eventQueue.offer(event, IAC_TIMEOUT, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { logger.debug("Can not put event '" + event.toString() + "' to FSM " + this.toString(), e); throw new InternalError("Can not put event '" + event.toString() + "' to FSM " + this.toString()); } if (!rc) { throw new OverloadException("FSM overloaded"); } return true; } //PCB added logging //private static long lastLogged; protected void setInActiveTimer() { timer = IAC_TIMEOUT - 2 * 1000 + random.nextInt(5) * 1000 + System.currentTimeMillis(); } @Override public String toString() { return "PeerFSM{" + "context=" + context + ", state=" + state + '}'; } @Override public E getState(Class a) { if (a == PeerState.class) { return (E) state.getPublicState(); } else { return null; } } protected abstract class MyState implements org.jdiameter.api.app.State { @Override public void entryAction() { } @Override public void exitAction() { } protected void doEndConnection() { if (context.isRestoreConnection()) { timer = REC_TIMEOUT + System.currentTimeMillis(); switchToNextState(REOPEN); } else { switchToNextState(DOWN); } } protected void doDisconnect() { try { context.disconnect(); } catch (Throwable e) { } } protected void setTimer(long value) { timer = value + System.currentTimeMillis(); } protected String key(StateEvent event) { return ((FsmEvent) event).getKey(); } protected IMessage message(StateEvent event) { return ((FsmEvent) event).getMessage(); } protected EventTypes type(StateEvent event) { return (EventTypes) event.getType(); } protected void clearTimer() { timer = 0; } } protected org.jdiameter.api.app.State[] getStates() { if (states == null) { states = new org.jdiameter.api.app.State[] { // todo merge and redesign with server fsm new MyState() { // OKEY @Override public void entryAction() { setInActiveTimer(); watchdogSent = false; } @Override public boolean processEvent(StateEvent event) { switch (event.encodeType(EventTypes.class)) { case DISCONNECT_EVENT: timer = REC_TIMEOUT + System.currentTimeMillis(); switchToNextState(FsmState.REOPEN); break; case TIMEOUT_EVENT: try { context.sendDwrMessage(); setTimer(DWA_TIMEOUT); if (watchdogSent) { switchToNextState(FsmState.SUSPECT); } else { watchdogSent = true; } } catch (Throwable e) { logger.debug("Can not send DWR", e); doDisconnect(); setTimer(REC_TIMEOUT); switchToNextState(FsmState.REOPEN); } break; case STOP_EVENT: try { if (event.getData() == null) { context.sendDprMessage(DisconnectCause.REBOOTING); } else { Integer disconnectCause = (Integer) event.getData(); context.sendDprMessage(disconnectCause); } setTimer(DPA_TIMEOUT); switchToNextState(FsmState.STOPPING); } catch (Throwable e) { logger.debug("Can not send DPR", e); doDisconnect(); switchToNextState(FsmState.DOWN); } break; case RECEIVE_MSG_EVENT: setInActiveTimer(); context.receiveMessage(message(event)); break; case DPR_EVENT: try { int code = context.processDprMessage(message(event)); context.sendDpaMessage(message(event), code, null); } catch (Throwable e) { logger.debug("Can not send DPA", e); } doDisconnect(); switchToNextState(FsmState.DOWN); break; case DWR_EVENT: setInActiveTimer(); try { int code = context.processDwrMessage(message(event)); context.sendDwaMessage(message(event), code, null); } catch (Throwable e) { logger.debug("Can not send DWA", e); doDisconnect(); switchToNextState(FsmState.DOWN); } break; case DWA_EVENT: setInActiveTimer(); watchdogSent = false; break; case SEND_MSG_EVENT: try { context.sendMessage(message(event)); } catch (Throwable e) { logger.debug("Can not send message", e); doDisconnect(); setTimer(REC_TIMEOUT); switchToNextState(FsmState.REOPEN); } break; default: logger.debug("Unknown event type: {} in state {}", event.encodeType(EventTypes.class), state); return false; } return true; } }, new MyState() { // SUSPECT @Override public boolean processEvent(StateEvent event) { switch (event.encodeType(EventTypes.class)) { case DISCONNECT_EVENT: setTimer(REC_TIMEOUT); switchToNextState(FsmState.REOPEN); break; case TIMEOUT_EVENT: doDisconnect(); setTimer(REC_TIMEOUT); switchToNextState(FsmState.REOPEN); break; case STOP_EVENT: try { if (event.getData() == null) { context.sendDprMessage(DisconnectCause.REBOOTING); } else { Integer disconnectCause = (Integer) event.getData(); context.sendDprMessage(disconnectCause); } setInActiveTimer(); switchToNextState(FsmState.STOPPING); } catch (Throwable e) { logger.debug("Can not send DPR", e); doDisconnect(); switchToNextState(FsmState.DOWN); } break; case DPR_EVENT: try { int code = context.processDprMessage(message(event)); context.sendDpaMessage(message(event), code, null); } catch (Throwable e) { logger.debug("Can not send DPA", e); } doDisconnect(); switchToNextState(FsmState.DOWN); break; case DWA_EVENT: switchToNextState(FsmState.OKAY); break; case DWR_EVENT: try { int code = context.processDwrMessage(message(event)); context.sendDwaMessage(message(event), code, null); switchToNextState(FsmState.OKAY); } catch (Throwable e) { logger.debug("Can not send DWA", e); doDisconnect(); switchToNextState(FsmState.DOWN); } break; case RECEIVE_MSG_EVENT: context.receiveMessage(message(event)); switchToNextState(FsmState.OKAY); break; case SEND_MSG_EVENT: throw new RuntimeException("Connection is down"); default: logger.debug("Unknown event type: {} in state {}", event.encodeType(EventTypes.class), state); return false; } return true; } }, new MyState() { // DOWN @Override public void entryAction() { clearTimer(); //PCB changed multithread FSM logger.debug("Setting mustRun to false @ Thread [{}]", Thread.currentThread().getName()); mustRun = false; logger.debug("Finished Setting mustRun to false @ Thread [{}]", Thread.currentThread().getName()); context.removeStatistics(); } @Override public boolean processEvent(StateEvent event) { switch (event.encodeType(EventTypes.class)) { case START_EVENT: try { context.createStatistics(); context.connect(); context.sendCerMessage(); setTimer(CEA_TIMEOUT); switchToNextState(FsmState.INITIAL); } catch (Throwable e) { logger.debug("Connect error", e); setTimer(REC_TIMEOUT); switchToNextState(FsmState.REOPEN); } break; case SEND_MSG_EVENT: throw new RuntimeException("Connection is down"); case STOP_EVENT: case DISCONNECT_EVENT: break; default: logger.debug("Unknown event type: {} in state {}", event.encodeType(EventTypes.class), state); return false; } return true; } }, new MyState() { // REOPEN @Override public boolean processEvent(StateEvent event) { switch (event.encodeType(EventTypes.class)) { case CONNECT_EVENT: try { context.sendCerMessage(); setTimer(CEA_TIMEOUT); switchToNextState(FsmState.INITIAL); } catch (Throwable e) { logger.debug("Can not send CER", e); setTimer(REC_TIMEOUT); } break; case TIMEOUT_EVENT: try { context.connect(); } catch (Exception e) { logger.debug("Timeout processed. Can not connect to {}", context.getPeerDescription()); setTimer(REC_TIMEOUT); } break; case STOP_EVENT: clearTimer(); doDisconnect(); switchToNextState(FsmState.DOWN); break; case DISCONNECT_EVENT: break; case SEND_MSG_EVENT: throw new IllegalStateException("Connection is down"); default: logger.debug("Unknown event type: {} in state {}", event.encodeType(EventTypes.class), state); return false; } return true; } }, new MyState() { // INITIAL @Override public void entryAction() { setTimer(CEA_TIMEOUT); } @Override public boolean processEvent(StateEvent event) { switch (event.encodeType(EventTypes.class)) { case DISCONNECT_EVENT: setTimer(REC_TIMEOUT); switchToNextState(FsmState.REOPEN); break; case TIMEOUT_EVENT: doDisconnect(); setTimer(REC_TIMEOUT); switchToNextState(FsmState.REOPEN); break; case STOP_EVENT: clearTimer(); doDisconnect(); switchToNextState(FsmState.DOWN); break; case CEA_EVENT: clearTimer(); if (context.processCeaMessage(((FsmEvent) event).getKey(), ((FsmEvent) event).getMessage())) { switchToNextState(FsmState.OKAY); } else { doDisconnect(); setTimer(REC_TIMEOUT); switchToNextState(FsmState.REOPEN); } break; case SEND_MSG_EVENT: throw new RuntimeException("Connection is down"); default: logger.debug("Unknown event type: {} in state {}", event.encodeType(EventTypes.class), state); return false; } return true; } }, new MyState() { // STOPPING @Override public boolean processEvent(StateEvent event) { switch (event.encodeType(EventTypes.class)) { case TIMEOUT_EVENT: case DPA_EVENT: doDisconnect(); switchToNextState(FsmState.DOWN); break; case RECEIVE_MSG_EVENT: context.receiveMessage(message(event)); break; case SEND_MSG_EVENT: throw new RuntimeException("Stack now is stopping"); case STOP_EVENT: case DISCONNECT_EVENT: doDisconnect(); break; default: logger.debug("Unknown event type: {} in state {}", event.encodeType(EventTypes.class), state); return false; } return true; } }, }; } return states; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/AppConfiguration.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import org.jdiameter.api.Configuration; /** * This interface provide methods for change configuration object * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface AppConfiguration extends Configuration { /** * Add elements to configuration * * @param e elements identifier * @param value array of elements * * @return instance of configuration */ AppConfiguration add(Ordinal e, Configuration... value); /** * @param e element identifier * @param value parameter value * * @return instance of configuration */ AppConfiguration add(Ordinal e, Object value); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/AssemblerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import org.jdiameter.api.Configuration; import org.jdiameter.client.api.IAssembler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Parameter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import static org.jdiameter.client.impl.helpers.ExtensionPoint.*; import static org.jdiameter.client.impl.helpers.Parameters.ExtensionName; import static org.jdiameter.client.impl.helpers.Parameters.Extensions; /** * IoC for stack * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AssemblerImpl implements IAssembler { private static final Logger logger = LoggerFactory.getLogger(AssemblerImpl.class); private final Map, Object> instances = new ConcurrentHashMap<>(); AssemblerImpl parent; final AssemblerImpl[] childs = new AssemblerImpl[ExtensionPoint.COUNT]; static private class LazyInstance extends Object { } /** * Create instance of class with predefined configuration * * @param config configuration of stack * @throws Exception if generated internal exception */ public AssemblerImpl(Configuration config) throws Exception { Configuration[] ext = config.getChildren(Extensions.ordinal()); for (Configuration e : ext) { String extName = e.getStringValue(ExtensionName.ordinal(), ""); // Create structure of containers if (extName.equals(ExtensionPoint.Internal.name())) { fill(ExtensionPoint.Internal.getExtensionPoints(), e, true); } else if (extName.equals(ExtensionPoint.StackLayer.name())) { updateContainer(config, StackLayer, InternalMetaData, InternalSessionFactory, InternalMessageParser, InternalElementParser); } else if (extName.equals(ExtensionPoint.ControllerLayer.name())) { updateContainer(config, ControllerLayer, InternalPeerController, InternalPeerFsmFactory, InternalRouterEngine); } else if (extName.equals(ExtensionPoint.TransportLayer.name())) { updateContainer(config, TransportLayer, InternalTransportFactory); } } } private void updateContainer(Configuration config, ExtensionPoint pointType, ExtensionPoint... updEntries) throws ClassNotFoundException { for (ExtensionPoint e : updEntries) { Configuration[] internalConf = config.getChildren(Extensions.ordinal()); String oldValue = internalConf[Internal.id()].getStringValue(e.ordinal(), null); String newValue = internalConf[pointType.id()].getStringValue(e.ordinal(), null); if (oldValue != null && newValue != null) { unregister(loadClass(oldValue)); registerComponentImplementation(loadClass(newValue)); } } } /** * Create child Assembler * * @param parent parent assembler * @param e child configuration * @param p extension poit * @throws Exception */ protected AssemblerImpl(AssemblerImpl parent, Configuration e, ExtensionPoint p) throws Exception { this.parent = parent; fill(p.getExtensionPoints(), e, false); } private Class loadClass(String className) throws ClassNotFoundException { return Thread.currentThread().getContextClassLoader().loadClass(className); } private void fill(ExtensionPoint[] codes, Configuration e, boolean check) throws Exception { //NOTE: this installs components, but no instances created! for (ExtensionPoint c : codes) { String value = e.getStringValue(c.ordinal(), c.defValue()); if (!check && (value == null || value.trim().length() == 0)) { return; } try { registerComponentImplementation(loadClass(value)); } catch (NoClassDefFoundError exc) { throw new Exception(exc); } } } private Object[] buildArgs(Parameter[] parameters) { List params = new ArrayList<>(); for (Parameter parameter : parameters) { Object arg = getComponentInstance(parameter.getType()); if (arg == null) { return null; } params.add(arg); } return params.toArray(); } private T newInstance(Class aClass) { List constructors = Arrays.asList(aClass.getConstructors()); constructors.sort((t1, t2) -> Integer.compare(t2.getParameters().length, t1.getParameters().length)); for (Constructor constructor : constructors) { Object[] args = buildArgs(constructor.getParameters()); if (args != null) { try { T instance = (T) constructor.newInstance(args); instances.put(aClass, instance); return instance; } catch (InvocationTargetException | InstantiationException | IllegalAccessException ex) { logger.error("Error instantiating {}", aClass, ex); } } //if } return null; } private T getInstance(Class aClass) { T instance = (T) instances.get(aClass); if (instance instanceof LazyInstance) { instance = newInstance(aClass); if (instance == null) { throw new IllegalArgumentException("Error creating a new instance of " + aClass); } instances.put(aClass, instance); } return instance; } /** * @see org.picocontainer.MutablePicoContainer */ @Override public T getComponentInstance(Class aClass) { if (aClass.isInterface()) { for (Class regClass : instances.keySet()) { if (aClass.isAssignableFrom(regClass)) { return (T) getInstance(regClass); } } } if (!instances.containsKey(aClass)) { logger.debug("No component instance found for {}", aClass); return null; } return getInstance(aClass); } /** * @see org.picocontainer.MutablePicoContainer */ @Override public void registerComponentInstance(Object object) { instances.put(object.getClass(), object); } public void registerComponentImplementation(Class aClass) { instances.put(aClass, new LazyInstance()); } /** * @see org.picocontainer.MutablePicoContainer */ @Override public void registerComponentImplementation(Class aClass, Object object) { instances.putIfAbsent(aClass, object); } public void unregister(Class aClass) { instances.remove(aClass); } @Override public void destroy() { instances.clear(); } /** * return parent IOC */ @Override public IAssembler getParent() { return parent; } /** * Get childs IOCs * * @return childs IOCs */ @Override public IAssembler[] getChilds() { return childs; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/EmptyConfiguration.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import static org.jdiameter.client.impl.helpers.ExtensionPoint.*; import static org.jdiameter.client.impl.helpers.Parameters.ExtensionName; import static org.jdiameter.client.impl.helpers.Parameters.Extensions; import java.util.concurrent.ConcurrentHashMap; import org.jdiameter.api.Configuration; /** * This class allow create configuration class for stack * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class EmptyConfiguration implements AppConfiguration { protected final Configuration[] EMPTY_ARRAY = new Configuration[0]; private final ConcurrentHashMap elements = new ConcurrentHashMap(); /** * Create instance of class with system default parameters * * @return instance of class with system default parameters */ public static AppConfiguration getInstance() { return new EmptyConfiguration(false); } /** * Create instance of class. Internal parameters will be appends */ protected EmptyConfiguration() { this(true); } /** * Create instance of class * * @param callInit if value is true then this constructor appends internal configuration parameters */ private EmptyConfiguration(boolean callInit) { if (callInit) { add(Extensions, getInstance(). // Internal extension point add(ExtensionName, ExtensionPoint.Internal.name()).add(InternalMetaData, InternalMetaData.defValue()) .add(InternalRouterEngine, InternalRouterEngine.defValue()) .add(InternalMessageParser, InternalMessageParser.defValue()) .add(InternalElementParser, InternalElementParser.defValue()) .add(InternalTransportFactory, InternalTransportFactory.defValue()) .add(InternalConnectionClass, InternalConnectionClass.defValue()) .add(InternalPeerFsmFactory, InternalPeerFsmFactory.defValue()) .add(InternalSessionFactory, InternalSessionFactory.defValue()) .add(InternalPeerController, InternalPeerController.defValue()) .add(InternalRealmController, InternalRealmController.defValue()) .add(InternalAgentRedirect, InternalAgentRedirect.defValue()) .add(InternalAgentConfiguration, InternalAgentConfiguration.defValue()) .add(InternalSessionDatasource, InternalSessionDatasource.defValue()) .add(InternalTimerFacility, InternalTimerFacility.defValue()) .add(InternalStatisticFactory, InternalStatisticFactory.defValue() ), getInstance(). // StackLayer extension point add(ExtensionName, ExtensionPoint.StackLayer.name()), getInstance(). // ControllerLayer extension point add(ExtensionName, ExtensionPoint.ControllerLayer.name()), getInstance(). // TransportLayer extension point add(ExtensionName, ExtensionPoint.TransportLayer.name())); } } /** * @see AppConfiguration class */ @Override public AppConfiguration add(Ordinal e, Configuration... value) { elements.put(e.ordinal(), value); return this; } /** * @see AppConfiguration class */ @Override public AppConfiguration add(Ordinal e, Object value) { if (value instanceof Configuration) { elements.put(e.ordinal(), new Configuration[] { (Configuration) value }); } else { elements.put(e.ordinal(), value); } return this; } protected void putValue(int key, Object value) { elements.put(key, value); } @Override public Object getValue(int key) { return elements.get(key); } protected void removeValue(int... keys) { for (int i : keys) { elements.remove(i); } } protected AppConfiguration add(int e, Configuration... value) { elements.put(e, value); return this; } /** * @see org.jdiameter.api.Configuration class */ @Override public byte getByteValue(int i, byte b) { return (Byte) (isAttributeExist(i) ? elements.get(i) : b); } /** * @see org.jdiameter.api.Configuration class */ @Override public int getIntValue(int i, int i1) { return (Integer) (isAttributeExist(i) ? elements.get(i) : i1); } /** * @see org.jdiameter.api.Configuration class */ @Override public long getLongValue(int i, long l) { return (Long) (isAttributeExist(i) ? elements.get(i) : l); } /** * @see org.jdiameter.api.Configuration class */ @Override public double getDoubleValue(int i, double v) { return (Double) (isAttributeExist(i) ? elements.get(i) : v); } /** * @see org.jdiameter.api.Configuration class */ @Override public byte[] getByteArrayValue(int i, byte[] bytes) { return (byte[]) (isAttributeExist(i) ? elements.get(i) : bytes); } /** * @see org.jdiameter.api.Configuration class */ @Override public boolean getBooleanValue(int i, boolean b) { return (Boolean) (isAttributeExist(i) ? elements.get(i) : b); } /** * @see org.jdiameter.api.Configuration class */ @Override public String getStringValue(int i, String defValue) { String result = (String) elements.get(i); return result != null ? result : defValue; } /** * @see org.jdiameter.api.Configuration class */ @Override public boolean isAttributeExist(int i) { return elements.containsKey(i); } /** * @see org.jdiameter.api.Configuration class */ @Override public Configuration[] getChildren(int i) { return (Configuration[]) elements.get(i); } /** * Return string representation of configuration * * @return string representation of configuration */ @Override public String toString() { StringBuffer buf = new StringBuffer("Configuration"); buf.append("{"); for (Integer key : elements.keySet()) { Object value = elements.get(key); Parameters pr = getParameterByIndex(key); if (pr == null) { continue; } if (pr.name().equals(Extensions.name())) { continue; } if (value instanceof Configuration[]) { buf.append('\n'); } buf.append(pr.name()); buf.append("="); if (value instanceof Configuration[]) { for (Configuration i : ((Configuration[]) value)) { buf.append(i.toString()).append('\n'); } } else { buf.append(value); } buf.append(", "); } buf.deleteCharAt(buf.length() - 1); buf.deleteCharAt(buf.length() - 1); buf.append("}"); return buf.toString(); } private Parameters getParameterByIndex(int index) { for (Parameters p : Parameters.values()) { if (p.ordinal() == index) { return p; } } return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/ExtensionPoint.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * This class provide pluggable features * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ExtensionPoint extends Ordinal { private static final long serialVersionUID = 1L; protected static int index; /** * MetaData implementation class name */ public static final ExtensionPoint InternalMetaData = new ExtensionPoint("InternalMetaData", "org.jdiameter.client.impl.MetaDataImpl"); /** * Message parser implementation class name */ public static final ExtensionPoint InternalMessageParser = new ExtensionPoint("InternalMessageParser", "org.jdiameter.client.impl.parser.MessageParser"); /** * Element message implementation class name */ public static final ExtensionPoint InternalElementParser = new ExtensionPoint("InternalElementParser", "org.jdiameter.client.impl.parser.ElementParser"); /** * Router enginr implementation class name */ public static final ExtensionPoint InternalRouterEngine = new ExtensionPoint("InternalRouterEngine", "org.jdiameter.client.impl.router.RouterImpl"); /** * Peer controller implementation class name */ public static final ExtensionPoint InternalPeerController = new ExtensionPoint("InternalPeerController", "org.jdiameter.client.impl.controller.PeerTableImpl"); /** * Realm controller implementation class name */ public static final ExtensionPoint InternalRealmController = new ExtensionPoint("InternalRealmController", "org.jdiameter.client.impl.controller.RealmTableImpl"); /** * Session factory implementation class name */ public static final ExtensionPoint InternalSessionFactory = new ExtensionPoint("InternalSessionFactory", "org.jdiameter.client.impl.SessionFactoryImpl"); /** * Class name of connection interface implementation */ public static final ExtensionPoint InternalConnectionClass = new ExtensionPoint("InternalConnection", "org.jdiameter.client.impl.transport.tcp.TCPClientConnection"); /** * Transport factory implementation class name */ public static final ExtensionPoint InternalTransportFactory = new ExtensionPoint("InternalTransportFactory", "org.jdiameter.client.impl.transport.TransportLayerFactory"); /** * Peer FSM factory implementation class name */ public static final ExtensionPoint InternalPeerFsmFactory = new ExtensionPoint("InternalPeerFsmFactory", "org.jdiameter.client.impl.fsm.FsmFactoryImpl"); /** * Statistic factory implementation class name */ public static final ExtensionPoint InternalStatisticFactory = new ExtensionPoint("InternalStatisticFactory", "org.jdiameter.common.impl.statistic.StatisticManagerImpl"); /** * Statistic factory implementation class name */ public static final ExtensionPoint InternalStatisticProcessor = new ExtensionPoint("InternalStatisticProcessor", "org.jdiameter.common.impl.statistic.StatisticProcessorImpl"); /** * Concurrent factory implementation class name */ public static final ExtensionPoint InternalConcurrentFactory = new ExtensionPoint("InternalConcurrentFactory", "org.jdiameter.common.impl.concurrent.ConcurrentFactory"); /** * Concurrent entity factory implementation class name */ public static final ExtensionPoint InternalConcurrentEntityFactory = new ExtensionPoint("InternalConcurrentEntityFactory", "org.jdiameter.common.impl.concurrent.ConcurrentEntityFactory"); /** * Redirect Agent implementation class name */ public static final ExtensionPoint InternalAgentRedirect = new ExtensionPoint("InternalAgentRedirect", "org.jdiameter.server.impl.agent.RedirectAgentImpl"); /** * Proxy Agent implementation class name */ public static final ExtensionPoint InternalAgentProxy = new ExtensionPoint("InternalAgentProxy", "org.jdiameter.server.impl.agent.ProxyAgentImpl"); /** * Agent Conf implementation class name */ public static final ExtensionPoint InternalAgentConfiguration = new ExtensionPoint("InternalAgentConfiguration", "org.jdiameter.server.impl.agent.AgentConfigurationImpl"); /** * Session Datasource class name */ public static final ExtensionPoint InternalSessionDatasource = new ExtensionPoint("InternalSessionDatasource", "org.jdiameter.common.impl.data.LocalDataSource"); /** * Timer Facility class name */ public static final ExtensionPoint InternalTimerFacility = new ExtensionPoint("InternalTimerFacility", "org.jdiameter.common.impl.timer.LocalTimerFacilityImpl"); /** * List of internal extension point */ public static final ExtensionPoint Internal = new ExtensionPoint( "Internal", 0, InternalMetaData, InternalMessageParser, InternalElementParser, InternalRouterEngine, InternalPeerController, InternalRealmController, InternalSessionFactory, //DONT add this, this will make assembler to try to create instance and he will fail :) //InternalConnectionClass, InternalTransportFactory, InternalPeerFsmFactory, InternalStatisticFactory, InternalConcurrentFactory, InternalConcurrentEntityFactory, InternalTimerFacility, InternalSessionDatasource, InternalAgentRedirect, InternalAgentProxy, InternalAgentConfiguration, InternalStatisticProcessor); /** * Stack layer */ public static final ExtensionPoint StackLayer = new ExtensionPoint("StackLayer", 1); /** * Controller layer */ public static final ExtensionPoint ControllerLayer = new ExtensionPoint("ControllerLayer", 2); /** * Transport layer */ public static final ExtensionPoint TransportLayer = new ExtensionPoint("TransportLayer", 3); private ExtensionPoint[] elements = new ExtensionPoint[0]; private String defaultValue = ""; private int id = -1; /** * Type's count of extension point */ public static final int COUNT = 3; /** * Create instance of class */ public ExtensionPoint() { this.ordinal = index++; } protected ExtensionPoint(String name, String defaultValue) { this(); this.name = name; this.defaultValue = defaultValue; } protected ExtensionPoint(String name, ExtensionPoint... elements) { this(); this.name = name; this.elements = elements; } protected ExtensionPoint(String name, int id, ExtensionPoint... elements) { this(); this.name = name; this.id = id; this.elements = elements; } /** * Append extension point entries * * @param elements array of append extension point entries */ public void appendElements(ExtensionPoint... elements) { List rc = new ArrayList(); rc.addAll(Arrays.asList(this.elements)); rc.addAll(Arrays.asList(elements)); this.elements = rc.toArray(new ExtensionPoint[0]); } /** * Return parameters of extension point * * @return array parameters of extension point */ public ExtensionPoint[] getExtensionPoints() { return elements; } /** * Return default value of extension point * * @return default value of extension point */ public String defValue() { return defaultValue; } /** * Return id of extension point * * @return id of extension point */ public int id() { return id; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/IPConverter.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.StringTokenizer; /** * This class allows to convert string to IPv4/IPv6 object instance * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class IPConverter { /** * Convert defined string to IPv4 object instance * * @param address string representation of ip address * * @return IPv4 object instance */ public static InetAddress InetAddressByIPv4(String address) { StringTokenizer addressTokens = new StringTokenizer(address, "."); byte[] bytes; if (addressTokens.countTokens() == 4) { bytes = new byte[] { getByBytes(addressTokens), getByBytes(addressTokens), getByBytes(addressTokens), getByBytes(addressTokens) }; } else { return null; } try { return InetAddress.getByAddress(bytes); } catch (UnknownHostException e) { return null; } } private static byte getByBytes(StringTokenizer addressTokens) { int word = Integer.parseInt(addressTokens.nextToken()); return (byte) (word & 0xff); } /** * Convert defined string to IPv6 object instance * * @param address string representation of ip address * * @return IPv6 object instance */ public static InetAddress InetAddressByIPv6(String address) { StringTokenizer addressTokens = new StringTokenizer(address, ":"); byte[] bytes = new byte[16]; if (addressTokens.countTokens() == 8) { int count = 0; while (addressTokens.hasMoreTokens()) { int word = Integer.parseInt(addressTokens.nextToken(), 16); bytes[count * 2] = (byte) ((word >> 8) & 0xff); bytes[count * 2 + 1] = (byte) (word & 0xff); count++; } } else { return null; } try { return InetAddress.getByAddress(bytes); } catch (UnknownHostException e) { return null; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Loggers.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import java.util.ArrayList; import java.util.logging.Logger; /** * This enumeration contains all logger usage in JDiameter stack implementation * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Loggers extends Ordinal { private static final long serialVersionUID = 1L; protected static int index; private static ArrayList value = new ArrayList(); /** * Logs the stack lifecycle */ public static final Loggers Stack = new Loggers("Stack", null, "Logs the stack lifecycle"); /** * Logs the peers */ public static final Loggers Peer = new Loggers("Peer", "peer", "Logs the peers"); /** * Logs the peer manager subsystem */ public static final Loggers PeerTable = new Loggers("PeerTable", "peertable", "Logs the peer table subsystem"); /** * Logs the peers fsm */ public static final Loggers FSM = new Loggers("FSM", "peer.fsm", "Logs the peers fsm"); /** * Logs the message parser */ public static final Loggers Parser = new Loggers("Parser", "parser", "Logs the message parser"); /** * Logs the avp opetations processing */ public static final Loggers AVP = new Loggers("AVP", "parser.avp", "Logs the avp opetations processing"); /** * Logs the message opetations/lifecycle processing */ public static final Loggers Message = new Loggers("Message", "parser.message", "Logs the message opetations/lifecycle processing"); /** * Logs the message router subsystem */ public static final Loggers Router = new Loggers("Router", "router", "Logs the message router subsystem"); /** * Logs the transport(tcp) opetations processing */ public static final Loggers Transport = new Loggers("Transport", "TCPTransport", "Logs the transport(tcp) opetations processing"); /** * Return Iterator of all entries * * @return Iterator of all entries */ public static Iterable values() { return value; } private String description; private String fullName; protected Loggers(String name, String fullName, String desc) { this.name = name; if (fullName == null) { this.fullName = "jDiameter"; } else { this.fullName = "jDiameter." + fullName; } this.description = desc; ordinal = index++; value.add(this); } /** * Return full name of logger * * @return full name of logger */ public String fullName() { return fullName; } /** * Return description of logger * * @return description of logger */ public String description() { return description; } /** * Return logger instance * * @return logger instance */ public Logger logger() { return Logger.getLogger(fullName); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Ordinal.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import java.io.Serializable; /** * This class provide ordinality properties to childs * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public abstract class Ordinal implements Serializable { private static final long serialVersionUID = 1L; protected String name; protected int ordinal; /** * Return name of element * * @return name of element */ public String name() { return name; } /** * Return id of element * * @return id of element */ public int ordinal() { return ordinal; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Parameters.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import java.util.ArrayList; /** * This enumeration defined all parameters of diameter stack implementation * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") public class Parameters extends Ordinal { private static final long serialVersionUID = 1L; protected static int index; private static ArrayList value = new ArrayList(); /** * Class name of IOC property */ public static final Parameters Assembler = new Parameters("Assembler", String.class, "org.jdiameter.client.impl.helpers.AssemblerImpl"); /** * Local peer URI property */ public static final Parameters OwnDiameterURI = new Parameters("OwnDiameterURI", String.class, "aaa://localhost:3868"); /** * Local peer ip address property */ public static final Parameters OwnIPAddress = new Parameters("OwnIPAddress", String.class, ""); /** * Local peer realm name property */ public static final Parameters OwnRealm = new Parameters("OwnRealm", String.class, "local"); /** * Local peer vendor id property */ public static final Parameters OwnVendorID = new Parameters("OwnVendorID", Long.class, 0L); /** * Local peer stack product name property */ public static final Parameters OwnProductName = new Parameters("OwnProductName", String.class, "jDiameter"); /** * Local peer stack firmware version property */ public static final Parameters OwnFirmwareRevision = new Parameters("OwnFirmwareRevision", Long.class, 0L); /** * Task executor task queue size property */ public static final Parameters QueueSize = new Parameters("QueueSize", Integer.class, 10000); /** * Message time out property */ public static final Parameters MessageTimeOut = new Parameters("MessageTimeOut", Long.class, 60000L); /** * Stop stack time out property */ public static final Parameters StopTimeOut = new Parameters("StopTimeOut", Long.class, 10000L); /** * CEA command time out property */ public static final Parameters CeaTimeOut = new Parameters("CeaTimeOut", Long.class, 10000L); /** * Peer inactive time out property */ public static final Parameters IacTimeOut = new Parameters("IacTimeOut", Long.class, 20000L); /** * DWA command time out property */ public static final Parameters DwaTimeOut = new Parameters("DwaTimeOut", Long.class, 10000L); /** * DPA command time out property */ public static final Parameters DpaTimeOut = new Parameters("DpaTimeOut", Long.class, 5000L); /** * Reconnect time out property */ public static final Parameters RecTimeOut = new Parameters("RecTimeOut", Long.class, 10000L); /** * Idle session time out property */ public static final Parameters SessionTimeOut = new Parameters("SessionTimeOut", Long.class, 0L); /** * Peer FSM Thread Count property */ public static final Parameters PeerFSMThreadCount = new Parameters("PeerFSMThreadCount", Integer.class, 3); /** * Orig_host avp set as URI into CER message */ public static final Parameters UseUriAsFqdn = new Parameters("UseUriAsFqdn", Boolean.class, false); /** * Virtual thread usage */ public static final Parameters UseVirtualThreads = new Parameters("UseVirtualThreads", Boolean.class, false); /** * Peer name property */ public static final Parameters PeerName = new Parameters("PeerName", String.class, ""); /** * Peer ip property */ public static final Parameters PeerIp = new Parameters("PeerIp", String.class, ""); /** * Peer local peer port range (format: 1345-1346) property */ public static final Parameters PeerLocalPortRange = new Parameters("PeerLocalPortRange", String.class, ""); /** * Peer rating property */ public static final Parameters PeerRating = new Parameters("PeerRating", Integer.class, 0); /** * Peer ptoperty */ public static final Parameters Peer = new Parameters("Peer", Object.class); /** * Real entry property */ public static final Parameters RealmEntry = new Parameters("RealmEntry", String.class, ""); /** * Agent element */ public static final Parameters Agent = new Parameters("Agent", Object.class); /** * Properties element */ public static final Parameters Properties = new Parameters("Properties", Object.class); /** * Properties element */ public static final Parameters Property = new Parameters("Property ", Object.class); /** * Property name */ public static final Parameters PropertyName = new Parameters("name", String.class, ""); /** * Property value */ public static final Parameters PropertyValue = new Parameters("value", String.class, ""); /** * Realm property */ public static final Parameters Realm = new Parameters("Realm", Object.class); /** * Vendor id property */ public static final Parameters VendorId = new Parameters("VendorId", Long.class); /** * Authentication application id property */ public static final Parameters AuthApplId = new Parameters("AuthApplId", Long.class); /** * Accounting application id property */ public static final Parameters AcctApplId = new Parameters("AcctApplId", Long.class); /** * Application Id property */ public static final Parameters ApplicationId = new Parameters("ApplicationId", Object.class); /** * Extension point property */ public static final Parameters Extensions = new Parameters("Extensions", Object.class); /** * Extension point name property */ public static final Parameters ExtensionName = new Parameters("ExtensionName", String.class); /** * Peer list property */ public static final Parameters PeerTable = new Parameters("PeerTable", Object.class); /** * Realm list property */ public static final Parameters RealmTable = new Parameters("RealmTable", Object.class); /** * Security list property */ public static final Parameters Security = new Parameters("Security", Object.class); /** * Security entry */ public static final Parameters SecurityData = new Parameters("SecurityData", Object.class); /** * Security data name */ public static final Parameters SDName = new Parameters("SDName", String.class); /** * Security protocol */ public static final Parameters SDProtocol = new Parameters("SDProtocol", String.class, "TLS"); /** * Security session creation flag */ public static final Parameters SDEnableSessionCreation = new Parameters("SDEnableSessionCreation", Boolean.class, false); /** * Security client mode flag */ public static final Parameters SDUseClientMode = new Parameters("SDUseClientMode", Boolean.class, false); /** * Cipher suites separated by ', ' */ public static final Parameters CipherSuites = new Parameters("CipherSuites", String.class); /** * Key data */ public static final Parameters KeyData = new Parameters("KeyData", String.class); /** * Key manager */ public static final Parameters KDManager = new Parameters("KDManager", String.class); /** * Key store */ public static final Parameters KDStore = new Parameters("KDStore", String.class); /** * Key file */ public static final Parameters KDFile = new Parameters("KDFile", String.class); /** * Key password */ public static final Parameters KDPwd = new Parameters("KDPwd", String.class); /** * Trust data */ public static final Parameters TrustData = new Parameters("TrustData", String.class); /** * Key manager */ public static final Parameters TDManager = new Parameters("TDManager", String.class); /** * Key store */ public static final Parameters TDStore = new Parameters("TDStore", String.class); /** * Key file */ public static final Parameters TDFile = new Parameters("TDFile", String.class); /** * Key password */ public static final Parameters TDPwd = new Parameters("TDPwd", String.class); /** * Reference to security information */ public static final Parameters SecurityRef = new Parameters("SecurityRef", String.class); /** * XML entry for thread pool */ public static final Parameters ThreadPool = new Parameters("ThreadPool", Object.class); /** * Thread pool max size */ public static final Parameters ThreadPoolSize = new Parameters("ThreadPoolSize", Integer.class, 10); /** * Thread pool max size */ public static final Parameters ThreadPoolPriority = new Parameters("ThreadPoolPriority", Integer.class, 5); /** * Statistic logger properties */ public static final Parameters Statistics = new Parameters("Statistics", Object.class); /** * Statistic logger start pause */ public static final Parameters StatisticsLoggerPause = new Parameters("StatisticsLoggerPause", Long.class, 30000L); /** * Statistic logger delay between save statistic information */ public static final Parameters StatisticsLoggerDelay = new Parameters("StatisticsLoggerDelay", Long.class, 30000L); /** * Statistic flag controlling if statistics are on/off - ie. timer tasks to display are created. */ public static final Parameters StatisticsEnabled = new Parameters("StatisticsEnabled", Boolean.class, false); /** * List of statistics names which should be enabled. */ public static final Parameters StatisticsActiveList = new Parameters("StatisticsActiveList", String.class, false); /** * Concurrent configuration root point */ public static final Parameters Concurrent = new Parameters("Concurrent", Object.class); /** * Concurrent entity name */ public static final Parameters ConcurrentEntityName = new Parameters("ConcurrentEntityName", String.class, "Empty"); /** * Concurrent thread group name */ public static final Parameters ConcurrentEntityDescription = new Parameters("ConcurrentEntityDescription", String.class, "ThreadPool"); /** * Concurrent thread group size */ public static final Parameters ConcurrentEntityPoolSize = new Parameters("ConcurrentEntityPoolSize", Integer.class, 4); /** * Dictionary root */ public static final Parameters Dictionary = new Parameters("Dictionary", Object.class); /** * Dictionary Class name */ public static final Parameters DictionaryClass = new Parameters("DictionaryClass", String.class, "org.jdiameter.common.impl.validation.DictionaryImpl"); /** * Dictionary Validation enabled */ public static final Parameters DictionaryEnabled = new Parameters("DictionaryEnabled", Boolean.class, false); /** * Dictionary Send Level Validation */ public static final Parameters DictionarySendLevel = new Parameters("DictionarySendLevel", String.class, "MESSAGE"); /** * Dictionary Receive Level Validation */ public static final Parameters DictionaryReceiveLevel = new Parameters("DictionaryReceiveLevel", String.class, "OFF"); /** * Return all parameters as iterator * * @return all parameters as iterator */ public static Iterable values() { return value; } private Class type; private Object defValue; protected Parameters(String name, Class type) { this.name = name; this.type = type; ordinal = index++; value.add(this); } protected Parameters(String name, Class type, Object defValue) { this.name = name; this.type = type; this.defValue = defValue; ordinal = index++; value.add(this); } /** * Return default value of property * * @return default value of property */ public Object defValue() { return defValue; } /** * Return type of property * * @return type of property */ public Class type() { return type; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/UIDGenerator.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * This class provide uid range generator functionality * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class UIDGenerator { // todo remove or redesign private /* static */ long value; // static causes repetitions private static final Lock mutex = new ReentrantLock(); private static final ThreadLocal ranges = new ThreadLocal() { @Override protected synchronized Delta initialValue() { return new Delta(); } }; private static class Delta { long start; long stop; public long update(long value) { start = value; stop = value + 1; return stop; } } /** * Create instance of class */ public UIDGenerator() { value = System.currentTimeMillis(); } /** * Create instance of class with predefined start value * * @param startValue start value of counter */ public UIDGenerator(long startValue) { value = startValue; } /** * Return next uid as int * * @return uid */ public int nextInt() { return (int) (0x7FFFFFFF & nextLong()); } /** * Return next uid as long * * @return uid as long */ public long nextLong() { Delta d = ranges.get(); if (d.start <= d.stop) { mutex.lock(); value = d.update(value); mutex.unlock(); } return d.start++; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/XMLConfiguration.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.helpers; import org.jdiameter.api.Configuration; import org.w3c.dom.*; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import static org.jdiameter.client.impl.helpers.ExtensionPoint.*; import static org.jdiameter.client.impl.helpers.Parameters.*; import static org.jdiameter.server.impl.helpers.Parameters.*; /** * This class provide loading and verification configuration for client from XML file * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class XMLConfiguration extends EmptyConfiguration { /** * Create instance of class and load file from defined input stream * * @param in input stream * @throws Exception */ public XMLConfiguration(InputStream in) throws Exception { this(in, null, null, false); } /** * Create instance of class and load file from defined input stream * * @param in input stream * @param attributes attributes for DocumentBuilderFactory * @param features features for DocumentBuilderFactory * @throws Exception */ public XMLConfiguration(InputStream in, Hashtable attributes, Hashtable features) throws Exception { this(in, attributes, features, false); } /** * Create instance of class and load file from defined file name * * @param filename configuration file name * @throws Exception */ public XMLConfiguration(String filename) throws Exception { this(filename, null, null, false); } /** * Create instance of class and load file from defined input stream * * @param filename configuration file name * @param attributes attributes for DocumentBuilderFactory * @param features features for DocumentBuilderFactory * @throws Exception */ public XMLConfiguration(String filename, Hashtable attributes, Hashtable features) throws Exception { this(filename, attributes, features, false); } protected XMLConfiguration(Object in, Hashtable attributes, Hashtable features, boolean nop) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); if (attributes != null) { for (String key : attributes.keySet()) { factory.setAttribute(key, attributes.get(key)); } } if (features != null) { for (String key : features.keySet()) { factory.setFeature(key, features.get(key)); } } DocumentBuilder builder = factory.newDocumentBuilder(); Document document; if (in instanceof InputStream) { document = builder.parse((InputStream) in); } else if (in instanceof String) { document = builder.parse(new File((String) in)); } else { throw new Exception("Unknown type of input data"); } validate(document); processing(document); } protected void validate(Document document) throws Exception { SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Source schemaFile = new StreamSource(getClass().getResourceAsStream("/META-INF/jdiameter-client.xsd")); Schema schema = factory.newSchema(schemaFile); Validator validator = schema.newValidator(); validator.validate(new DOMSource(document)); } protected void processing(Document document) { Element element = document.getDocumentElement(); NodeList c = element.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("LocalPeer")) { addLocalPeer(c.item(i)); } else if (nodeName.equals("Parameters")) { addParameters(c.item(i)); } else if (nodeName.equals("Network")) { addNetwork(c.item(i)); } else if (nodeName.equals("Security")) { addSecurity(c.item(i)); } else if (nodeName.equals("Extensions")) { addExtensions(c.item(i)); } } } protected void addLocalPeer(Node node) { NodeList c = node.getChildNodes(); if (node.getAttributes().getNamedItem("security_ref") != null) { add(SecurityRef, node.getAttributes().getNamedItem("security_ref").getNodeValue()); } for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("URI")) { add(OwnDiameterURI, getValue(c.item(i))); } addIPAddress(c.item(i)); if (nodeName.equals("Realm")) { add(OwnRealm, getValue(c.item(i))); } if (nodeName.equals("VendorID")) { add(OwnVendorID, getLongValue(c.item(i))); } if (nodeName.equals("ProductName")) { add(OwnProductName, getValue(c.item(i))); } if (nodeName.equals("FirmwareRevision")) { add(OwnFirmwareRevision, getLongValue(c.item(i))); } if (nodeName.equals("Applications")) { addApplications(c.item(i)); } } } protected void addIPAddress(Node node) { String nodeName = node.getNodeName(); if (nodeName.equals("IPAddress")) { add(OwnIPAddress, getValue(node)); } } protected void addApplications(Node node) { NodeList c = node.getChildNodes(); ArrayList items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("ApplicationID")) { items.add(addApplication(c.item(i))); } } add(ApplicationId, items.toArray(EMPTY_ARRAY)); } protected Configuration addApplication(Node node) { NodeList c = node.getChildNodes(); AppConfiguration e = getInstance(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("VendorId")) { e.add(VendorId, getLongValue(c.item(i))); } else if (nodeName.equals("AuthApplId")) { e.add(AuthApplId, getLongValue(c.item(i))); } else if (nodeName.equals("AcctApplId")) { e.add(AcctApplId, getLongValue(c.item(i))); } } return e; } protected void addParameters(Node node) { NodeList c = node.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("UseUriAsFqdn")) { add(UseUriAsFqdn, Boolean.valueOf(getValue(c.item(i)))); } else if (nodeName.equals("UseVirtualThreads")) { add(UseVirtualThreads, Boolean.valueOf(getValue(c.item(i)))); } else if (nodeName.equals("QueueSize")) { add(QueueSize, getIntValue(c.item(i))); } else if (nodeName.equals("MessageTimeOut")) { add(MessageTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("StopTimeOut")) { add(StopTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("CeaTimeOut")) { add(CeaTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("IacTimeOut")) { add(IacTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("DwaTimeOut")) { add(DwaTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("DpaTimeOut")) { add(DpaTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("RecTimeOut")) { add(RecTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("PeerFSMThreadCount")) { add(PeerFSMThreadCount, getIntValue(c.item(i))); } else if (nodeName.equals("Statistics")) { addStatisticLogger(Statistics, c.item(i)); } else if (nodeName.equals("Concurrent")) { addConcurrent(Concurrent, c.item(i)); } else if (nodeName.equals("Dictionary")) { addDictionary(Dictionary, c.item(i)); } else { appendOtherParameter(c.item(i)); } } } protected void addConcurrent(org.jdiameter.client.impl.helpers.Parameters name, Node node) { NodeList c = node.getChildNodes(); List items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Entity")) { addConcurrentEntity(items, c.item(i)); } } add(name, items.toArray(new Configuration[items.size()])); } protected void addConcurrentEntity(List items, Node node) { AppConfiguration cfg = getInstance(); String name = node.getAttributes().getNamedItem("name").getNodeValue(); cfg.add(ConcurrentEntityName, name); if (node.getAttributes().getNamedItem("description") != null) { String descr = node.getAttributes().getNamedItem("description").getNodeValue(); cfg.add(ConcurrentEntityDescription, descr); } if (node.getAttributes().getNamedItem("size") != null) { String size = node.getAttributes().getNamedItem("size").getNodeValue(); cfg.add(ConcurrentEntityPoolSize, Integer.parseInt(size)); } items.add(cfg); } protected void addStatisticLogger(org.jdiameter.client.impl.helpers.Parameters name, Node node) { String pause = node.getAttributes().getNamedItem("pause").getNodeValue(); String delay = node.getAttributes().getNamedItem("delay").getNodeValue(); String enabled = node.getAttributes().getNamedItem("enabled").getNodeValue(); String active_records; if (node.getAttributes().getNamedItem("active_records") != null) { active_records = node.getAttributes().getNamedItem("active_records").getNodeValue(); } else { active_records = (String) StatisticsActiveList.defValue(); } add(name, getInstance().add(StatisticsLoggerPause, Long.parseLong(pause)) .add(StatisticsLoggerDelay, Long.parseLong(delay)) .add(StatisticsEnabled, Boolean.parseBoolean(enabled)) .add(StatisticsActiveList, active_records)); } protected void addDictionary(org.jdiameter.client.impl.helpers.Parameters name, Node node) { AppConfiguration dicConfiguration = getInstance(); Node param = node.getAttributes().getNamedItem("class"); if (param != null) { String clazz = param.getNodeValue(); dicConfiguration.add(DictionaryClass, clazz); } param = node.getAttributes().getNamedItem("enabled"); if (param != null) { String enabled = param.getNodeValue(); dicConfiguration.add(DictionaryEnabled, Boolean.valueOf(enabled)); } param = node.getAttributes().getNamedItem("sendLevel"); if (param != null) { String sendLevel = param.getNodeValue(); dicConfiguration.add(DictionarySendLevel, sendLevel); } param = node.getAttributes().getNamedItem("receiveLevel"); if (param != null) { String receiveLevel = param.getNodeValue(); dicConfiguration.add(DictionaryReceiveLevel, receiveLevel); } add(name, dicConfiguration); } protected void appendOtherParameter(Node node) { } protected void addThreadPool(Node item) { AppConfiguration threadPoolConfiguration = EmptyConfiguration.getInstance(); NamedNodeMap attributes = item.getAttributes(); for (int index = 0; index < attributes.getLength(); index++) { Node n = attributes.item(index); int v = Integer.parseInt(n.getNodeValue()); if (n.getNodeName().equals("size")) { threadPoolConfiguration.add(ThreadPoolSize, v); } else if (n.getNodeName().equals("priority")) { threadPoolConfiguration.add(ThreadPoolPriority, v); } else { //log.error("Unkonwn attribute on " + item.getNodeName() + ", attribute name: " + n.getNodeName()); } } if (!threadPoolConfiguration.isAttributeExist(ThreadPoolSize.ordinal())) { threadPoolConfiguration.add(ThreadPoolSize, ThreadPoolSize.defValue()); } if (!threadPoolConfiguration.isAttributeExist(ThreadPoolPriority.ordinal())) { threadPoolConfiguration.add(ThreadPoolPriority, ThreadPoolPriority.defValue()); } this.add(ThreadPool, threadPoolConfiguration); } protected void addSecurity(Node node) { NodeList c = node.getChildNodes(); List items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("SecurityData")) { items.add(addSecurityData(c.item(i))); } } add(Security, items.toArray(EMPTY_ARRAY)); } protected Configuration addSecurityData(Node node) { AppConfiguration sd = getInstance().add(SDName, node.getAttributes().getNamedItem("name").getNodeValue()) .add(SDProtocol, node.getAttributes().getNamedItem("protocol").getNodeValue()) .add(SDEnableSessionCreation, Boolean.valueOf(node.getAttributes().getNamedItem("enable_session_creation").getNodeValue())) .add(SDUseClientMode, Boolean.valueOf(node.getAttributes().getNamedItem("use_client_mode").getNodeValue())); NodeList c = node.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { Node cnode = c.item(i); String nodeName = cnode.getNodeName(); if (nodeName.equals("CipherSuites")) { sd.add(CipherSuites, cnode.getTextContent().trim()); } if (nodeName.equals("KeyData")) { sd.add(KeyData, getInstance().add(KDManager, cnode.getAttributes().getNamedItem("manager").getNodeValue()) .add(KDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) .add(KDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) .add(KDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); } if (nodeName.equals("TrustData")) { sd.add(TrustData, getInstance().add(TDManager, cnode.getAttributes().getNamedItem("manager").getNodeValue()) .add(TDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) .add(TDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) .add(TDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); } } return sd; } protected void addNetwork(Node node) { NodeList c = node.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Peers")) { addPeers(c.item(i)); } else if (nodeName.equals("Realms")) { addRealms(c.item(i)); } } } protected void addPeers(Node node) { NodeList c = node.getChildNodes(); ArrayList items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Peer")) { items.add(addPeer(c.item(i))); } } add(PeerTable, items.toArray(EMPTY_ARRAY)); } protected void addRealms(Node node) { NodeList c = node.getChildNodes(); ArrayList items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Realm")) { items.add(addRealm(c.item(i))); } } add(RealmTable, items.toArray(EMPTY_ARRAY)); } protected Configuration addPeer(Node node) { AppConfiguration peerConfig = getInstance() .add(PeerRating, Integer.valueOf(node.getAttributes().getNamedItem("rating").getNodeValue())) .add(PeerName, node.getAttributes().getNamedItem("name").getNodeValue()); if (node.getAttributes().getNamedItem("ip") != null) { peerConfig.add(PeerIp, node.getAttributes().getNamedItem("ip").getNodeValue()); } if (node.getAttributes().getNamedItem("portRange") != null) { peerConfig.add(PeerLocalPortRange, node.getAttributes().getNamedItem("portRange").getNodeValue()); } if (node.getAttributes().getNamedItem("security_ref") != null) { peerConfig.add(SecurityRef, node.getAttributes().getNamedItem("security_ref").getNodeValue()); } return peerConfig; } protected Configuration addRealm(Node node) { AppConfiguration realmEntry = getInstance() .add(ApplicationId, new Configuration[]{addApplicationID(node.getChildNodes())}) .add(RealmName, getAttrValue(node, "name")).add(RealmHosts, getAttrValue(node, "peers")) .add(RealmLocalAction, getAttrValue(node, "local_action")) .add(RealmEntryIsDynamic, Boolean.valueOf(getAttrValue(node, "dynamic"))) .add(RealmEntryExpTime, Long.valueOf(getAttrValue(node, "exp_time"))); NodeList childNodes = node.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { String nodeName = childNodes.item(i).getNodeName(); if (nodeName.equals("Agent")) { realmEntry.add(Agent, addAgent(childNodes.item(i))); } } return getInstance().add(RealmEntry, realmEntry); } protected Configuration addAgent(Node node) { AppConfiguration agentConf = getInstance(); NodeList agentChildren = node.getChildNodes(); for (int index = 0; index < agentChildren.getLength(); index++) { Node n = agentChildren.item(index); if (n.getNodeName().equals("Properties")) { agentConf.add(Properties, getProperties(n).toArray(EMPTY_ARRAY)); } } return agentConf; } protected List getProperties(Node node) { List props = new ArrayList(); NodeList propertiesChildren = node.getChildNodes(); for (int index = 0; index < propertiesChildren.getLength(); index++) { Node n = propertiesChildren.item(index); if (n.getNodeName().equals("Property")) { AppConfiguration property = getInstance(); property.add(PropertyName, n.getAttributes().getNamedItem(PropertyName.name()).getNodeValue()); property.add(PropertyValue, n.getAttributes().getNamedItem(PropertyValue.name()).getNodeValue()); props.add(property); } } return props; } protected Configuration addApplicationID(NodeList node) { for (int i = 0; i < node.getLength(); i++) { String nodeName = node.item(i).getNodeName(); if (nodeName.equals("ApplicationID")) { return addApplicationID(node.item(i)); } } return null; } protected Configuration addApplicationID(Node node) { NodeList c = node.getChildNodes(); AppConfiguration e = getInstance(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("VendorId")) { e.add(VendorId, getLongValue(c.item(i))); } else if (nodeName.equals("AuthApplId")) { e.add(AuthApplId, getLongValue(c.item(i))); } else if (nodeName.equals("AcctApplId")) { e.add(AcctApplId, getLongValue(c.item(i))); } } return e; } protected void addExtensions(Node node) { NodeList c = node.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("MetaData")) { addInternalExtension(InternalMetaData, getValue(c.item(i))); } else if (nodeName.equals("MessageParser")) { addInternalExtension(InternalMessageParser, getValue(c.item(i))); } else if (nodeName.equals("ElementParser")) { addInternalExtension(InternalElementParser, getValue(c.item(i))); } else if (nodeName.equals("RouterEngine")) { addInternalExtension(InternalRouterEngine, getValue(c.item(i))); } else if (nodeName.equals("PeerController")) { addInternalExtension(InternalPeerController, getValue(c.item(i))); } else if (nodeName.equals("RealmController")) { addInternalExtension(InternalRealmController, getValue(c.item(i))); } else if (nodeName.equals("SessionFactory")) { addInternalExtension(InternalSessionFactory, getValue(c.item(i))); } else if (nodeName.equals("TransportFactory")) { addInternalExtension(InternalTransportFactory, getValue(c.item(i))); } else if (nodeName.equals("Connection")) { addInternalExtension(InternalConnectionClass, getValue(c.item(i))); } else if (nodeName.equals("PeerFsmFactory")) { addInternalExtension(InternalPeerFsmFactory, getValue(c.item(i))); } else if (nodeName.equals("StatisticFactory")) { addInternalExtension(InternalStatisticFactory, getValue(c.item(i))); } else if (nodeName.equals("ConcurrentFactory")) { addInternalExtension(InternalConcurrentFactory, getValue(c.item(i))); } else if (nodeName.equals("ConcurrentEntityFactory")) { addInternalExtension(InternalConcurrentEntityFactory, getValue(c.item(i))); } else if (nodeName.equals("SessionDatasource")) { addInternalExtension(InternalSessionDatasource, getValue(c.item(i))); } else if (nodeName.equals("TimerFacility")) { addInternalExtension(InternalTimerFacility, getValue(c.item(i))); } //FIXME: possibly should not be in client... else if (nodeName.equals("AgentRedirect")) { addInternalExtension(InternalAgentRedirect, getValue(c.item(i))); } else if (nodeName.equals("AgentConfiguration")) { add(InternalAgentConfiguration, getValue(c.item(i))); } else if (nodeName.equals("StatisticProcessor")) { addInternalExtension(InternalStatisticProcessor, getValue(c.item(i))); } else { appendOtherExtension(c.item(i)); } } } protected void addInternalExtension(Ordinal ep, String value) { Configuration[] extensionConfs = this.getChildren(org.jdiameter.client.impl.helpers.Parameters.Extensions.ordinal()); AppConfiguration internalExtensions = (AppConfiguration) extensionConfs[ExtensionPoint.Internal.id()]; internalExtensions.add(ep, value); } private void appendOtherExtension(Node item) { // Nothing to do here, so far... } protected Long getLongValue(Node node) { return Long.valueOf(getValue(node)); } protected Integer getIntValue(Node node) { return Integer.valueOf(getValue(node)); } protected String getValue(Node node) { return node.getAttributes().getNamedItem("value").getNodeValue(); } protected String getAttrValue(Node node, String name) { return node.getAttributes().getNamedItem(name).getNodeValue(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/AvpImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.parser; import java.net.InetAddress; import java.net.URISyntaxException; import java.net.UnknownServiceException; import java.util.Date; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.InternalException; import org.jdiameter.api.URI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class AvpImpl implements Avp { private static final long serialVersionUID = 1L; private static final ElementParser parser = new ElementParser(); int avpCode; long vendorID; boolean isMandatory = false; boolean isEncrypted = false; boolean isVendorSpecific = false; byte[] rawData = new byte[0]; AvpSet groupedData; private static final Logger logger = LoggerFactory.getLogger(AvpImpl.class); AvpImpl(int code, int flags, long vnd, byte[] data) { avpCode = code; // isMandatory = (flags & 0x40) != 0; isEncrypted = (flags & 0x20) != 0; isVendorSpecific = (flags & 0x80) != 0; // vendorID = vnd; rawData = data; } AvpImpl(Avp avp) { avpCode = avp.getCode(); vendorID = avp.getVendorId(); isMandatory = avp.isMandatory(); isEncrypted = avp.isEncrypted(); isVendorSpecific = avp.isVendorId(); try { rawData = avp.getRaw(); if (rawData == null || rawData.length == 0) { groupedData = avp.getGrouped(); } } catch (AvpDataException e) { logger.debug("Can not create Avp", e); } } AvpImpl(int newCode, Avp avp) { this(avp); avpCode = newCode; } @Override public int getCode() { return avpCode; } @Override public boolean isVendorId() { return isVendorSpecific; } @Override public boolean isMandatory() { return isMandatory; } @Override public boolean isEncrypted() { return isEncrypted; } @Override public long getVendorId() { return vendorID; } @Override public byte[] getRaw() throws AvpDataException { return rawData; } @Override public byte[] getOctetString() throws AvpDataException { return rawData; } @Override public String getUTF8String() throws AvpDataException { try { return parser.bytesToUtf8String(rawData); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public int getInteger32() throws AvpDataException { try { return parser.bytesToInt(rawData); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public long getInteger64() throws AvpDataException { try { return parser.bytesToLong(rawData); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public long getUnsigned32() throws AvpDataException { try { byte[] u32ext = new byte[8]; System.arraycopy(rawData, 0, u32ext, 4, 4); return parser.bytesToLong(u32ext); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public long getUnsigned64() throws AvpDataException { try { return parser.bytesToLong(rawData); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public float getFloat32() throws AvpDataException { try { return parser.bytesToFloat(rawData); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public double getFloat64() throws AvpDataException { try { return parser.bytesToDouble(rawData); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public InetAddress getAddress() throws AvpDataException { try { return parser.bytesToAddress(rawData); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public Date getTime() throws AvpDataException { try { return parser.bytesToDate(rawData); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public String getDiameterIdentity() throws AvpDataException { try { return parser.bytesToOctetString(rawData); } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public URI getDiameterURI() throws AvpDataException { try { return new URI(parser.bytesToOctetString(rawData)); } catch (URISyntaxException e) { throw new AvpDataException(e, this); } catch (UnknownServiceException e) { throw new AvpDataException(e, this); } } @Override public AvpSet getGrouped() throws AvpDataException { try { if (groupedData == null) { groupedData = parser.decodeAvpSet(rawData); rawData = new byte[0]; } return groupedData; } catch (Exception e) { throw new AvpDataException(e, this); } } @Override public boolean isWrapperFor(Class aClass) throws InternalException { return false; } @Override public T unwrap(Class aClass) throws InternalException { return null; } @Override public byte[] getRawData() { return (rawData == null || rawData.length == 0) ? parser.encodeAvpSet(groupedData) : rawData; } // Caching toString.. Avp shouldn't be modified once created. private String toString; @Override public String toString() { if (toString == null) { this.toString = new StringBuffer("AvpImpl [avpCode=").append(avpCode).append(", vendorID=").append(vendorID) .append(", len=").append((rawData != null) ? rawData.length : null).append("]@").append(super.hashCode()) .toString(); } return this.toString; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/AvpSetImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.parser; import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Iterator; import java.util.List; /* * https://jdiameter.dev.java.net/ * * License: GPL v3 * * e-mail: erick.svenson@yahoo.com * */ import org.jdiameter.api.Avp; import org.jdiameter.api.AvpSet; import org.jdiameter.api.InternalException; import org.jdiameter.api.URI; import org.jdiameter.client.api.parser.ParseException; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Grzegorz Figiel [ProIDS] */ @SuppressWarnings("all") //3rd party lib class AvpSetImpl implements AvpSet { // FIXME: by default 3588.4-1 says: 'M' should be set to true; // FIXME: by default 3588.x says: if grouped has at least on AVP with 'M' set, it also has to have 'M' set! - TODO: add backmapping. private static final long serialVersionUID = 1L; private static final ElementParser parser = new ElementParser(); List avps = new ArrayList(); AvpSetImpl() { } @Override public Avp getAvp(int avpCode) { for (Avp avp : this.avps) { if (avp.getCode() == avpCode) { return avp; } } return null; } @Override public Avp getAvpByIndex(int avpIndex) { return this.avps.get(avpIndex); } @Override public Avp getAvp(int avpCode, long vendorId) { for (Avp avp : this.avps) { if (avp.getCode() == avpCode && avp.getVendorId() == vendorId) { return avp; } } return null; } @Override public AvpSet getAvps(int avpCode) { AvpSet result = new AvpSetImpl(); for (Avp avp : this.avps) { if (avp.getCode() == avpCode) { result.addAvp(avp); } } return result; } @Override public AvpSet getAvps(int avpCode, long vendorId) { AvpSet result = new AvpSetImpl(); for (Avp avp : this.avps) { if (avp.getCode() == avpCode && avp.getVendorId() == vendorId) { result.addAvp(avp); } } return result; } @Override public int getAvpIndex(int avpCode) { for (Avp avp : this.avps) { if (avp.getCode() == avpCode) { return this.avps.indexOf(avp); } } return -1; } @Override public int getAvpIndex(int avpCode, long vendorId) { for (Avp avp : this.avps) { if (avp.getCode() == avpCode && avp.getVendorId() == vendorId) { return this.avps.indexOf(avp); } } return -1; } @Override public AvpSet removeAvp(int avpCode) { return removeAvp(avpCode, 0); } @Override public AvpSet removeAvp(int avpCode, long vendorId) { AvpSet result = new AvpSetImpl(); // for (Avp avp : this.avps) { // if (avp.getCode() == avpCode) { // result.addAvp(avp); // this.avps.remove(avp); // } // } Iterator it = this.avps.iterator(); while (it.hasNext()) { Avp avp = it.next(); if (avp.getCode() == avpCode && avp.getVendorId() == vendorId) { result.addAvp(avp); it.remove(); } } return result; } @Override public Avp removeAvpByIndex(int i) { return (i >= this.avps.size()) ? null : this.avps.remove(i); } @Override public Avp[] asArray() { return this.avps.toArray(new Avp[avps.size()]); } @Override public Avp addAvp(int avpCode, long value, boolean asUnsigned) { Avp res = new AvpImpl(avpCode, 0, 0, asUnsigned ? parser.intU32ToBytes(value) : parser.int64ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, long value, boolean mFlag, boolean pFlag, boolean asUnsigned) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, asUnsigned ? parser.intU32ToBytes(value) : parser.int64ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, long value, long vndId, boolean mFlag, boolean pFlag, boolean asUnsigned) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, asUnsigned ? parser.intU32ToBytes(value) : parser.int64ToBytes(value)); this.avps.add(res); return res; } @Override public void insertAvp(int index, Avp... avps) { this.avps.addAll(index, Arrays.asList(avps)); } @Override public void insertAvp(int index, AvpSet avpSet) { this.avps.addAll(index, Arrays.asList(avpSet.asArray())); } @Override public Avp insertAvp(int index, int avpCode, long value, boolean asUnsigned) { Avp res = new AvpImpl(avpCode, 0, 0, asUnsigned ? parser.intU32ToBytes(value) : parser.int64ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, long value, boolean mFlag, boolean pFlag, boolean asUnsigned) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, asUnsigned ? parser.intU32ToBytes(value) : parser.int64ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, long value, long vndId, boolean mFlag, boolean pFlag, boolean asUnsigned) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, asUnsigned ? parser.intU32ToBytes(value) : parser.int64ToBytes(value)); this.avps.add(index, res); return res; } @Override public AvpSet insertGroupedAvp(int index, int avpCode) { AvpImpl res = new AvpImpl(avpCode, 0, 0, new byte[0]); res.groupedData = new AvpSetImpl(); this.avps.add(index, res); return res.groupedData; } @Override public int size() { return this.avps.size(); } @Override public void addAvp(AvpSet avpSet) { for (Avp a : avpSet) { avps.add(a); } } @Override public void addAvp(Avp... avps) { for (Avp a : avps) { // No need to clone AVP, right? // Avp res = new AvpImpl(a); if (a != null) { this.avps.add(a); } } } @Override public Avp addAvp(int avpCode, byte[] rawData) { Avp res = new AvpImpl(avpCode, 0, 0, rawData); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, byte[] rawData, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, rawData); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, byte[] rawData, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, rawData); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, int value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.int32ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, int value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.int32ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, int value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.int32ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, long value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.int64ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, long value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.int64ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, long value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.int64ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, float value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.float32ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, float value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.float32ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, float value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.float32ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, double value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.float64ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, double value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.float64ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, double value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.float64ToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, String value, boolean asOctetString) { try { Avp res = new AvpImpl(avpCode, 0, 0, asOctetString ? parser.octetStringToBytes(value) : parser.utf8StringToBytes(value)); this.avps.add(res); return res; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public Avp addAvp(int avpCode, String value, boolean mFlag, boolean pFlag, boolean asOctetString) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); try { Avp res = new AvpImpl(avpCode, flags, 0, asOctetString ? parser.octetStringToBytes(value) : parser.utf8StringToBytes(value)); this.avps.add(res); return res; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public Avp addAvp(int avpCode, String value, long vndId, boolean mFlag, boolean pFlag, boolean asOctetString) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); try { Avp res = new AvpImpl(avpCode, flags, vndId, asOctetString ? parser.octetStringToBytes(value) : parser.utf8StringToBytes(value)); this.avps.add(res); return res; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public Avp addAvp(int avpCode, URI value) { try { Avp res = new AvpImpl(avpCode, 0, 0, parser.octetStringToBytes(value.toString())); this.avps.add(res); return res; } catch (ParseException e) { throw new IllegalArgumentException(e); } } @Override public Avp addAvp(int avpCode, URI value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); try { Avp res = new AvpImpl(avpCode, flags, 0, parser.octetStringToBytes(value.toString())); this.avps.add(res); return res; } catch (ParseException e) { throw new IllegalArgumentException(e); } } @Override public Avp addAvp(int avpCode, URI value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); try { Avp res = new AvpImpl(avpCode, flags, vndId, parser.octetStringToBytes(value.toString())); this.avps.add(res); return res; } catch (ParseException e) { throw new IllegalArgumentException(e); } } @Override public Avp addAvp(int avpCode, InetAddress value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.addressToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, InetAddress value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.addressToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, InetAddress value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.addressToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, Date value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.dateToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, Date value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.dateToBytes(value)); this.avps.add(res); return res; } @Override public Avp addAvp(int avpCode, Date value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.dateToBytes(value)); this.avps.add(res); return res; } @Override public AvpSet addGroupedAvp(int avpCode) { AvpImpl res = new AvpImpl(avpCode, 0, 0, new byte[0]); res.groupedData = new AvpSetImpl(); this.avps.add(res); return res.groupedData; } @Override public AvpSet addGroupedAvp(int avpCode, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); AvpImpl res = new AvpImpl(avpCode, flags, 0, new byte[0]); res.groupedData = new AvpSetImpl(); this.avps.add(res); return res.groupedData; } @Override public AvpSet addGroupedAvp(int avpCode, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); AvpImpl res = new AvpImpl(avpCode, flags, vndId, new byte[0]); res.groupedData = new AvpSetImpl(); this.avps.add(res); return res.groupedData; } @Override public Avp insertAvp(int index, int avpCode, byte[] value) { Avp res = new AvpImpl(avpCode, 0, 0, value); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, byte[] value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, value); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, byte[] value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, value); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, int value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.int32ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, int value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.int32ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, int value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.int32ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, long value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.int64ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, long value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.int64ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, long value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.int64ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, float value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.float32ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, float value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.float32ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, float value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.float32ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, double value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.float64ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, double value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.float64ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, double value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.float64ToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, String value, boolean asOctetString) { try { Avp res = new AvpImpl(avpCode, 0, 0, asOctetString ? parser.octetStringToBytes(value) : parser.utf8StringToBytes(value)); this.avps.add(index, res); return res; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public Avp insertAvp(int index, int avpCode, String value, boolean mFlag, boolean pFlag, boolean asOctetString) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); try { Avp res = new AvpImpl(avpCode, flags, 0, asOctetString ? parser.octetStringToBytes(value) : parser.utf8StringToBytes(value)); this.avps.add(index, res); return res; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public Avp insertAvp(int index, int avpCode, String value, long vndId, boolean mFlag, boolean pFlag, boolean asOctetString) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); try { Avp res = new AvpImpl(avpCode, flags, vndId, asOctetString ? parser.octetStringToBytes(value) : parser.utf8StringToBytes(value)); this.avps.add(index, res); return res; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public Avp insertAvp(int index, int avpCode, URI value) { try { Avp res = new AvpImpl(avpCode, 0, 0, parser.octetStringToBytes(value.toString())); this.avps.add(index, res); return res; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public Avp insertAvp(int index, int avpCode, URI value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); try { Avp res = new AvpImpl(avpCode, flags, 0, parser.octetStringToBytes(value.toString())); this.avps.add(index, res); return res; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public Avp insertAvp(int index, int avpCode, URI value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); try { Avp res = new AvpImpl(avpCode, flags, vndId, parser.octetStringToBytes(value.toString())); this.avps.add(index, res); return res; } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public Avp insertAvp(int index, int avpCode, InetAddress value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.addressToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, InetAddress value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.addressToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, InetAddress value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.addressToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, Date value) { Avp res = new AvpImpl(avpCode, 0, 0, parser.dateToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, Date value, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, 0, parser.dateToBytes(value)); this.avps.add(index, res); return res; } @Override public Avp insertAvp(int index, int avpCode, Date value, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); Avp res = new AvpImpl(avpCode, flags, vndId, parser.dateToBytes(value)); this.avps.add(index, res); return res; } @Override public AvpSet insertGroupedAvp(int index, int avpCode, boolean mFlag, boolean pFlag) { int flags = ((mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); AvpImpl res = new AvpImpl(avpCode, flags, 0, new byte[0]); res.groupedData = new AvpSetImpl(); this.avps.add(index, res); return res.groupedData; } @Override public AvpSet insertGroupedAvp(int index, int avpCode, long vndId, boolean mFlag, boolean pFlag) { int flags = ((vndId != 0 ? 0x80 : 0) | (mFlag ? 0x40 : 0) | (pFlag ? 0x20 : 0)); AvpImpl res = new AvpImpl(avpCode, flags, vndId, new byte[0]); res.groupedData = new AvpSetImpl(); this.avps.add(index, res); return res.groupedData; } @Override public boolean isWrapperFor(Class aClass) throws InternalException { return false; } @Override public T unwrap(Class aClass) throws InternalException { return null; } @Override public Iterator iterator() { // Iterator contract demands it to be able to remove items // return Collections.unmodifiableList(this.avps).iterator(); return this.avps.iterator(); } @Override public String toString() { return new StringBuffer("AvpSetImpl [avps=").append(avps).append("]@").append(super.hashCode()).toString(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/ElementParser.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.parser; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.UncheckedIOException; import java.io.UnsupportedEncodingException; import java.net.Inet4Address; import java.net.InetAddress; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Date; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.client.api.parser.IElementParser; import org.jdiameter.client.api.parser.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * erick.svenson@yahoo.com * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ElementParser implements IElementParser { private static final Logger logger = LoggerFactory.getLogger(ElementParser.class); /** * This is seconds shift (70 years in seconds) applied to date, since NTP date starts since 1900, not 1970. */ private static final long SECOND_SHIFT = 2208988800L; private static final int INT_INET4 = 1; private static final int INT_INET6 = 2; private static final int INT32_SIZE = 4; private static final int INT64_SIZE = 8; @Override public int bytesToInt(byte[] rawData) throws AvpDataException { // http://stackoverflow.com/a/9581858 return (rawData[0] & 0xFF) << 24 | (rawData[1] & 0xFF) << 16 | (rawData[2] & 0xFF) << 8 | (rawData[3] & 0xFF) << 0; } @Override public long bytesToLong(byte[] rawData) throws AvpDataException { // http://stackoverflow.com/a/1026804 return (rawData[0] & 0xFFL) << 56 | (rawData[1] & 0xFFL) << 48 | (rawData[2] & 0xFFL) << 40 | (rawData[3] & 0xFFL) << 32 | (rawData[4] & 0xFFL) << 24 | (rawData[5] & 0xFFL) << 16 | (rawData[6] & 0xFFL) << 8 | (rawData[7] & 0xFFL) << 0; } public long bytesToUnsignedInt32(byte[] rawData) throws AvpDataException { byte[] u32ext = new byte[INT64_SIZE]; System.arraycopy(rawData, 0, u32ext, 4, 4); return bytesToLong(u32ext); } @Override public float bytesToFloat(byte[] rawData) throws AvpDataException { // http://stackoverflow.com/a/14308765 return Float.intBitsToFloat(bytesToInt(rawData)); } @Override public double bytesToDouble(byte[] rawData) throws AvpDataException { return Double.longBitsToDouble(bytesToLong(rawData)); } @Override public String bytesToOctetString(byte[] rawData) throws AvpDataException { try { return new String(rawData, "iso-8859-1"); } catch (UnsupportedEncodingException e) { throw new AvpDataException("Invalid data type", e); } } @Override public String bytesToUtf8String(byte[] rawData) throws AvpDataException { try { return new String(rawData, "utf8"); } catch (UnsupportedEncodingException e) { throw new AvpDataException("Invalid data type", e); } } @Override public Date bytesToDate(byte[] rawData) throws AvpDataException { try { byte[] tmp = new byte[8]; System.arraycopy(rawData, 0, tmp, 4, 4); return new Date(((bytesToLong(tmp) - SECOND_SHIFT) * 1000L)); } catch (Exception e) { throw new AvpDataException(e); } } @Override public InetAddress bytesToAddress(byte[] rawData) throws AvpDataException { InetAddress inetAddress; try { boolean isIPv6 = rawData[INT_INET4] != INT_INET4; byte[] address = new byte[isIPv6 ? 16 : 4]; System.arraycopy(rawData, 2, address, 0, address.length); inetAddress = isIPv6 ? InetAddress.getByAddress(address) : InetAddress.getByAddress(address); } catch (Exception e) { throw new AvpDataException(e); } return inetAddress; } @Override public byte[] int32ToBytes(int value) { byte[] bytes = new byte[INT32_SIZE]; bytes[0] = (byte) (value >> 24 & 0xFF); bytes[1] = (byte) (value >> 16 & 0xFF); bytes[2] = (byte) (value >> 8 & 0xFF); bytes[3] = (byte) (value >> 0 & 0xFF); return bytes; } @Override public byte[] intU32ToBytes(long value) { byte[] bytes = int64ToBytes(value); return new byte[] { bytes[4], bytes[5], bytes[6], bytes[7] }; } @Override public byte[] int64ToBytes(long value) { byte[] bytes = new byte[INT64_SIZE]; bytes[0] = (byte) (value >> 56 & 0xFF); bytes[1] = (byte) (value >> 48 & 0xFF); bytes[2] = (byte) (value >> 40 & 0xFF); bytes[3] = (byte) (value >> 32 & 0xFF); bytes[4] = (byte) (value >> 24 & 0xFF); bytes[5] = (byte) (value >> 16 & 0xFF); bytes[6] = (byte) (value >> 8 & 0xFF); bytes[7] = (byte) (value >> 0 & 0xFF); return bytes; } @Override public byte[] float32ToBytes(float value) { // http://stackoverflow.com/a/14308774 return int32ToBytes(Float.floatToIntBits(value)); } @Override public byte[] float64ToBytes(double value) { return int64ToBytes(Double.doubleToLongBits(value)); } @Override public byte[] octetStringToBytes(String value) throws ParseException { try { return value.getBytes("iso-8859-1"); } catch (UnsupportedEncodingException e) { throw new ParseException(e); } } @Override public byte[] utf8StringToBytes(String value) throws ParseException { try { return value.getBytes("utf8"); } catch (Exception e) { throw new ParseException(e); } } @Override public byte[] addressToBytes(InetAddress address) { byte[] byteAddrOrig = address.getAddress(); byte[] data = new byte[byteAddrOrig.length + 2]; int addrType = address instanceof Inet4Address ? INT_INET4 : INT_INET6; data[0] = (byte) ((addrType >> 8) & 0xFF); data[INT_INET4] = (byte) ((addrType >> 0) & 0xFF); System.arraycopy(byteAddrOrig, 0, data, 2, byteAddrOrig.length); return data; } @Override public byte[] dateToBytes(Date date) { byte[] data = new byte[4]; System.arraycopy(int64ToBytes((date.getTime() / 1000L) + SECOND_SHIFT), 4, data, 0, 4); return data; } @Override public T bytesToObject(java.lang.Class iface, byte[] rawdata) throws AvpDataException { return null; } @Override public byte[] objectToBytes(Object data) throws ParseException { return null; } public AvpSetImpl decodeAvpSet(byte[] buffer) { try { return this.decodeAvpSet(buffer, 0); } //try catch (IOException ex) { throw new UncheckedIOException(ex); } //catch catch (AvpDataException ex) { throw new UncheckedIOException(new IOException(ex)); } //catch } /** * @param buffer * @param shift - shift in buffer, for instance for whole message it will have non zero value * * @return * * @throws IOException * @throws AvpDataException */ public AvpSetImpl decodeAvpSet(byte[] buffer, int shift) throws IOException, AvpDataException { AvpSetImpl avps = new AvpSetImpl(); int tmp, counter = shift; DataInputStream in = new DataInputStream(new ByteArrayInputStream(buffer, shift, buffer.length /* - shift ? */)); while (counter < buffer.length) { int code = in.readInt(); tmp = in.readInt(); int flags = (tmp >> 24) & 0xFF; int length = tmp & 0xFFFFFF; if (length < 0 || counter + length > buffer.length) { throw new AvpDataException("Not enough data in buffer!"); } long vendor = 0; boolean hasVendor = false; if ((flags & 0x80) != 0) { vendor = in.readInt(); hasVendor = true; } // Determine body L = length - 4(code) -1(flags) -3(length) [-4(vendor)] byte[] rawData = new byte[length - (8 + (hasVendor ? 4 : 0))]; in.read(rawData); // skip remaining. // TODO: Do we need to padd everything? Or on send stack should properly fill byte[] ... ? if (length % 4 != 0) { for (int i; length % 4 != 0; length += i) { i = (int) in.skip((4 - length % 4)); } } AvpImpl avp = new AvpImpl(code, (short) flags, (int) vendor, rawData); avps.addAvp(avp); counter += length; } return avps; } public byte[] encodeAvpSet(AvpSet avps) { //ByteArrayOutputStream out = new ByteArrayOutputStream(); DynamicByteArray dba = new DynamicByteArray(0); try { //DataOutputStream data = new DataOutputStream(out); for (Avp a : avps) { if (a instanceof AvpImpl) { AvpImpl aImpl = (AvpImpl) a; if (aImpl.rawData.length == 0 && aImpl.groupedData != null) { aImpl.rawData = encodeAvpSet(a.getGrouped()); } //data.write(newEncodeAvp(aImpl)); dba.add(encodeAvp(aImpl)); } } } catch (Exception e) { e.printStackTrace(); logger.debug("Error during encode avps", e); } return dba.getResult(); } protected class DynamicByteArray { private byte[] array; private int size; public DynamicByteArray(int cap) { array = new byte[cap > 0 ? cap : 256]; size = 0; } public int get(int pos) { if (pos >= size) { throw new ArrayIndexOutOfBoundsException(); } return array[pos]; } public void add(byte[] bytes) { if (size + bytes.length > array.length) { byte[] newarray = new byte[array.length + bytes.length * 2]; System.arraycopy(array, 0, newarray, 0, size); array = newarray; } System.arraycopy(bytes, 0, array, size, bytes.length); size += bytes.length; } public byte[] getResult() { return Arrays.copyOfRange(array, 0, size); } } public byte[] encodeAvp(AvpImpl avp) { try { int payloadSize = avp.getRaw().length; boolean hasVendorId = avp.getVendorId() != 0; int origLength = payloadSize + 8 + (hasVendorId ? 4 : 0); int tmp = payloadSize % 4; int paddingSize = tmp > 0 ? (4 - tmp) : 0; byte[] bCode = this.int32ToBytes(avp.getCode()); int flags = (byte) ((hasVendorId ? 0x80 : 0) | (avp.isMandatory() ? 0x40 : 0) | (avp.isEncrypted() ? 0x20 : 0)); byte[] bFlags = this.int32ToBytes(((flags << 24) & 0xFF000000) + origLength); byte[] bVendor = hasVendorId ? int32ToBytes((int) avp.getVendorId()) : new byte[0]; return concat(origLength + paddingSize, bCode, bFlags, bVendor, avp.getRaw()); } catch (Exception e) { logger.debug("Error during encode avp", e); return new byte[0]; } } private byte[] concat(int length, byte[]... arrays) { if (length == 0) { for (byte[] array : arrays) { length += array.length; } } byte[] result = new byte[length]; int pos = 0; for (byte[] array : arrays) { System.arraycopy(array, 0, result, pos, array.length); pos += array.length; } return result; } protected ByteBuffer prepareBuffer(byte[] bytes, int len) throws AvpDataException { if (bytes.length != len) { throw new AvpDataException("Incorrect data length"); } return ByteBuffer.wrap(bytes); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.parser; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.InternalException; import org.jdiameter.client.api.IEventListener; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.impl.router.RouterImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Represents a Diameter message. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class MessageImpl implements IMessage { private static final long serialVersionUID = 1L; private static final Logger logger = LoggerFactory.getLogger(MessageImpl.class); private static final MessageParser parser = new MessageParser(); int state = STATE_NOT_SENT; short version = 1, flags; int commandCode; long applicationId; long hopByHopId; boolean notMutableHopByHop; long endToEndId; AvpSetImpl avpSet; boolean isNetworkRequest = false; transient IPeer peer; transient TimerTask timerTask; transient IEventListener listener; // Cached result for getApplicationIdAvps() method. It is called extensively and takes some time. // Potential place for dirt, but Application IDs don't change during message life time. transient List applicationIds; /** * Create empty message * * @param parser * @param commandCode * @param appId */ MessageImpl(int commandCode, long appId) { this.commandCode = commandCode; this.applicationId = appId; this.avpSet = new AvpSetImpl(); this.endToEndId = parser.getNextEndToEndId(); } /** * Create empty message * * @param parser * @param commandCode * @param applicationId * @param flags * @param hopByHopId * @param endToEndId * @param avpSet */ MessageImpl(int commandCode, long applicationId, short flags, long hopByHopId, long endToEndId, AvpSetImpl avpSet) { this(commandCode, applicationId); this.flags = flags; this.hopByHopId = hopByHopId; this.endToEndId = endToEndId; if (avpSet != null) { this.avpSet = avpSet; } } // /** // * Create empty message // * // * @param metaData // * @param parser // * @param commandCode // * @param appId // */ // MessageImpl(MetaData metaData, MessageParser parser, int commandCode, long appId) { // this(commandCode, appId); // try { // getAvps().addAvp(Avp.ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); // getAvps().addAvp(Avp.ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); // } // catch (Exception e) { // logger.debug("Can not create message", e); // } // } /** * Create Answer * * @param request parent request */ private MessageImpl(MessageImpl request) { this(request.getCommandCode(), request.getHeaderApplicationId()); copyHeader(request); setRequest(false); parser.copyBasicAvps(this, request, true); // if we set REQUEST_TABLE_SIZE to 0, we store routing info at answer if (RouterImpl.REQUEST_TABLE_SIZE == 0) { addRoutingInfo(request); } } private String[] routingInfo = { null, null }; private void addRoutingInfo(MessageImpl request) { for (Avp a : request.getAvps()) { if (a.getCode() == Avp.ORIGIN_HOST) { try { routingInfo[0] = a.getDiameterIdentity(); if (routingInfo[1] != null) { return; } } catch (AvpDataException e) { logger.error("Unable to read Origin-Host AVP value for storing Routing Info", e); } } else if (a.getCode() == Avp.ORIGIN_REALM) { try { routingInfo[1] = a.getDiameterIdentity(); if (routingInfo[0] != null) { return; } } catch (AvpDataException e) { logger.error("Unable to read Origin-Realm AVP value for storing Routing Info", e); } } } } public String[] getRoutingInfo() { return routingInfo; } @Override public byte getVersion() { return (byte) version; } @Override public boolean isRequest() { return (flags & 0x80) != 0; } @Override public void setRequest(boolean b) { if (b) { flags |= 0x80; } else { flags &= 0x7F; } } @Override public boolean isProxiable() { return (flags & 0x40) != 0; } @Override public void setProxiable(boolean b) { if (b) { flags |= 0x40; } else { flags &= 0xBF; } } @Override public boolean isError() { return (flags & 0x20) != 0; } @Override public void setError(boolean b) { if (b) { flags |= 0x20; } else { flags &= 0xDF; } } @Override public boolean isReTransmitted() { return (flags & 0x10) != 0; } @Override public void setReTransmitted(boolean b) { if (b) { flags |= 0x10; } else { flags &= 0xEF; } } @Override public int getCommandCode() { return this.commandCode; } @Override public String getSessionId() { try { Avp avpSessionId = avpSet.getAvp(Avp.SESSION_ID); return avpSessionId != null ? avpSessionId.getUTF8String() : null; } catch (AvpDataException ade) { logger.error("Failed to fetch Session-Id", ade); return null; } } @Override public Answer createAnswer() { MessageImpl answer = new MessageImpl(this); return answer; } @Override public Answer createAnswer(long resultCode) { MessageImpl answer = new MessageImpl(this); try { answer.getAvps().addAvp(Avp.RESULT_CODE, resultCode, true, false, true); } catch (Exception e) { logger.debug("Can not create answer message", e); } //Its set in constructor. //answer.setRequest(false); return answer; } @Override public Answer createAnswer(long vendorId, long experimentalResultCode) { MessageImpl answer = new MessageImpl(this); try { AvpSet exp_code = answer.getAvps().addGroupedAvp(297, true, false); exp_code.addAvp(Avp.VENDOR_ID, vendorId, true, false, true); exp_code.addAvp(Avp.EXPERIMENTAL_RESULT_CODE, experimentalResultCode, true, false, true); } catch (Exception e) { logger.debug("Can not create answer message", e); } answer.setRequest(false); return answer; } @Override public long getApplicationId() { return applicationId; } @Override public ApplicationId getSingleApplicationId() { return getSingleApplicationId(this.applicationId); } @Override public List getApplicationIdAvps() { if (this.applicationIds != null) { return this.applicationIds; } List rc = new ArrayList(); try { AvpSet authAppId = avpSet.getAvps(Avp.AUTH_APPLICATION_ID); for (Avp anAuthAppId : authAppId) { rc.add(ApplicationId.createByAuthAppId((anAuthAppId).getInteger32())); } AvpSet accAppId = avpSet.getAvps(Avp.ACCT_APPLICATION_ID); for (Avp anAccAppId : accAppId) { rc.add(ApplicationId.createByAccAppId((anAccAppId).getInteger32())); } AvpSet specAppId = avpSet.getAvps(Avp.VENDOR_SPECIFIC_APPLICATION_ID); for (Avp aSpecAppId : specAppId) { long vendorId = 0, acctApplicationId = 0, authApplicationId = 0; AvpSet avps = (aSpecAppId).getGrouped(); for (Avp localAvp : avps) { if (localAvp.getCode() == Avp.VENDOR_ID) { vendorId = localAvp.getUnsigned32(); } if (localAvp.getCode() == Avp.AUTH_APPLICATION_ID) { authApplicationId = localAvp.getUnsigned32(); } if (localAvp.getCode() == Avp.ACCT_APPLICATION_ID) { acctApplicationId = localAvp.getUnsigned32(); } } if (authApplicationId != 0) { rc.add(ApplicationId.createByAuthAppId(vendorId, authApplicationId)); } if (acctApplicationId != 0) { rc.add(ApplicationId.createByAccAppId(vendorId, acctApplicationId)); } } } catch (Exception exception) { return new ArrayList(); } this.applicationIds = rc; return this.applicationIds; } @Override public ApplicationId getSingleApplicationId(long applicationId) { logger.debug("In getSingleApplicationId for application id [{}]", applicationId); List appIds = getApplicationIdAvps(); logger.debug("Application Ids in this message are:"); ApplicationId firstOverall = null; ApplicationId firstWithZeroVendor = null; ApplicationId firstWithNonZeroVendor = null; for (ApplicationId id : appIds) { logger.debug("[{}]", id); if (firstOverall == null) { firstOverall = id; } if (applicationId != 0) { if (firstWithZeroVendor == null && id.getVendorId() == 0 && (applicationId == id.getAuthAppId() || applicationId == id.getAcctAppId())) { firstWithZeroVendor = id; } if (firstWithNonZeroVendor == null && id.getVendorId() != 0 && (applicationId == id.getAuthAppId() || applicationId == id.getAcctAppId())) { firstWithNonZeroVendor = id; break; } } } ApplicationId toReturn = null; if (firstWithNonZeroVendor != null) { toReturn = firstWithNonZeroVendor; logger.debug("Returning [{}] as the first application id because its the first vendor specific one found", toReturn); } else if (firstWithZeroVendor != null) { toReturn = firstWithZeroVendor; logger.debug("Returning [{}] as the first application id because there are no vendor specific ones found", toReturn); } else { toReturn = firstOverall; logger.debug("Returning [{}] as the first application id because none with the requested app ids were found", toReturn); } if (toReturn == null) { // TODO: ammendonca: improve this (find vendor? use common app list map?) logger.debug( "There are no Application-Id AVPs. Using the value in the header and assuming as Auth Application-Id [{}]", this.applicationId); toReturn = ApplicationId.createByAuthAppId(this.applicationId); } return toReturn; } @Override public long getHopByHopIdentifier() { return hopByHopId; } @Override public long getEndToEndIdentifier() { return endToEndId; } @Override public AvpSet getAvps() { return avpSet; } protected void copyHeader(MessageImpl request) { endToEndId = request.endToEndId; hopByHopId = request.hopByHopId; version = request.version; flags = request.flags; peer = request.peer; } @Override public Avp getResultCode() { return getAvps().getAvp(Avp.RESULT_CODE); } @Override public void setNetworkRequest(boolean isNetworkRequest) { this.isNetworkRequest = isNetworkRequest; } @Override public boolean isNetworkRequest() { return isNetworkRequest; } @Override public boolean isWrapperFor(Class aClass) throws InternalException { return false; } @Override public T unwrap(Class aClass) throws InternalException { return null; } // Inner API @Override public void setHopByHopIdentifier(long hopByHopId) { if (hopByHopId < 0) { this.hopByHopId = -hopByHopId; this.notMutableHopByHop = true; } else { if (!this.notMutableHopByHop) { this.hopByHopId = hopByHopId; } } } @Override public void setEndToEndIdentifier(long endByEndId) { this.endToEndId = endByEndId; } @Override public IPeer getPeer() { return peer; } @Override public void setPeer(IPeer peer) { this.peer = peer; } @Override public int getState() { return state; } @Override public long getHeaderApplicationId() { return applicationId; } @Override public void setHeaderApplicationId(long applicationId) { this.applicationId = applicationId; } @Override public int getFlags() { return flags; } @Override public void setState(int newState) { state = newState; } @Override public void createTimer(ScheduledExecutorService scheduledFacility, long timeOut, TimeUnit timeUnit) { timerTask = new TimerTask(this); timerTask.setTimerHandler(scheduledFacility, scheduledFacility.schedule(timerTask, timeOut, timeUnit)); } @Override public void runTimer() { if (timerTask != null && !timerTask.isDone() && !timerTask.isCancelled()) { timerTask.run(); } } @Override public boolean isTimeOut() { return timerTask != null && timerTask.isDone() && !timerTask.isCancelled(); } @Override public void setListener(IEventListener listener) { this.listener = listener; } @Override public IEventListener getEventListener() { return listener; } @Override public void clearTimer() { if (timerTask != null) { timerTask.cancel(); } } @Override public String toString() { return "MessageImpl{" + "commandCode=" + commandCode + ", flags=" + flags + '}'; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } MessageImpl message = (MessageImpl) o; return applicationId == message.applicationId && commandCode == message.commandCode && endToEndId == message.endToEndId && hopByHopId == message.hopByHopId; } @Override public int hashCode() { long result; result = commandCode; result = 31 * result + applicationId; result = 31 * result + hopByHopId; result = 31 * result + endToEndId; return Long.valueOf(result).hashCode(); } @Override public String getDuplicationKey() { try { return getDuplicationKey(getAvps().getAvp(Avp.ORIGIN_HOST).getDiameterIdentity(), getEndToEndIdentifier()); } catch (AvpDataException e) { throw new IllegalArgumentException(e); } } @Override public String getDuplicationKey(String host, long endToEndId) { return host + endToEndId; } @Override public Object clone() { try { return parser.createMessage(parser.encodeMessage(this)); } catch (Exception e) { throw new IllegalArgumentException(e); } } protected static class TimerTask implements Runnable { ScheduledFuture timerHandler; MessageImpl message; ScheduledExecutorService scheduledFacility; public TimerTask(MessageImpl message) { this.message = message; } public void setTimerHandler(ScheduledExecutorService scheduledFacility, ScheduledFuture timerHandler) { this.scheduledFacility = scheduledFacility; this.timerHandler = timerHandler; } @Override public void run() { try { if (message != null && message.state != STATE_ANSWERED) { IEventListener listener = null; if (message.listener instanceof IEventListener) { listener = message.listener; } if (listener != null && listener.isValid()) { if (message.peer != null) { message.peer.remMessage(message); } message.listener.timeoutExpired(message); } } } catch (Throwable e) { logger.debug("Can not process timeout", e); } } public void cancel() { if (timerHandler != null) { timerHandler.cancel(true); if (scheduledFacility instanceof ThreadPoolExecutor && timerHandler instanceof Runnable) { ((ThreadPoolExecutor) scheduledFacility).remove((Runnable) timerHandler); } } message = null; } public boolean isDone() { return timerHandler != null && timerHandler.isDone(); } public boolean isCancelled() { return timerHandler == null || timerHandler.isCancelled(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/parser/MessageParser.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.parser; import static org.jdiameter.api.Avp.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.nio.ByteBuffer; import java.util.concurrent.TimeUnit; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Request; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.client.impl.helpers.UIDGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class MessageParser extends ElementParser implements IMessageParser { private static final Logger logger = LoggerFactory.getLogger(MessageParser.class); protected UIDGenerator endToEndGen = new UIDGenerator( (int) (TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) & 0xFFF) << 20); public MessageParser() { } @Override public IMessage createMessage(byte[] message) throws AvpDataException { // Read header try { long tmp; DataInputStream in = new DataInputStream(new ByteArrayInputStream(message)); tmp = in.readInt(); short version = (short) (tmp >> 24); if (version != 1) { throw new Exception("Illegal value of version " + version); } if (message.length != (tmp & 0x00FFFFFF)) { //throw new ParseException("Wrong length of data: " + (tmp & 0x00FFFFFF)); throw new Exception("Wrong length of data: " + (tmp & 0x00FFFFFF)); } tmp = in.readInt(); short flags = (short) ((tmp >> 24) & 0xFF); int commandCode = (int) (tmp & 0xFFFFFF); long applicationId = ((long) in.readInt() << 32) >>> 32; long hopByHopId = ((long) in.readInt() << 32) >>> 32; long endToEndId = ((long) in.readInt() << 32) >>> 32; // Read body // byte[] body = new byte[message.length - 20]; // System.arraycopy(message, 20, body, 0, body.length); // AvpSetImpl avpSet = decodeAvpSet(body); AvpSetImpl avpSet = decodeAvpSet(message, 20); return new MessageImpl(commandCode, applicationId, flags, hopByHopId, endToEndId, avpSet); } catch (Exception exc) { throw new AvpDataException(exc); } } @Override public IMessage createMessage(ByteBuffer data) throws AvpDataException { byte[] message = data.array(); return createMessage(message); } @Override public T createMessage(Class iface, ByteBuffer data) throws AvpDataException { if (iface == IMessage.class) { return (T) createMessage(data); } return null; } @Override public T createEmptyMessage(Class iface, IMessage parentMessage) { if (iface == Request.class) { return (T) createEmptyMessage(parentMessage, parentMessage.getCommandCode()); } else { return null; } } @Override public IMessage createEmptyMessage(IMessage prnMessage) { return createEmptyMessage(prnMessage, prnMessage.getCommandCode()); } @Override public IMessage createEmptyMessage(IMessage prnMessage, int commandCode) { // MessageImpl newMessage = new MessageImpl( commandCode, prnMessage.getHeaderApplicationId(), (short) prnMessage.getFlags(), prnMessage.getHopByHopIdentifier(), endToEndGen.nextLong(), null); copyBasicAvps(newMessage, prnMessage, false); return newMessage; } void copyBasicAvps(IMessage newMessage, IMessage prnMessage, boolean invertPoints) { //left it here, but Avp avp; // Copy session id's information { avp = prnMessage.getAvps().getAvp(SESSION_ID); if (avp != null) { newMessage.getAvps().addAvp(new AvpImpl(avp)); } avp = prnMessage.getAvps().getAvp(Avp.ACC_SESSION_ID); if (avp != null) { newMessage.getAvps().addAvp(new AvpImpl(avp)); } avp = prnMessage.getAvps().getAvp(Avp.ACC_SUB_SESSION_ID); if (avp != null) { newMessage.getAvps().addAvp(new AvpImpl(avp)); } avp = prnMessage.getAvps().getAvp(Avp.ACC_MULTI_SESSION_ID); if (avp != null) { newMessage.getAvps().addAvp(new AvpImpl(avp)); } } // Copy Applicatio id's information { avp = prnMessage.getAvps().getAvp(VENDOR_SPECIFIC_APPLICATION_ID); if (avp != null) { newMessage.getAvps().addAvp(new AvpImpl(avp)); } avp = prnMessage.getAvps().getAvp(ACCT_APPLICATION_ID); if (avp != null) { newMessage.getAvps().addAvp(new AvpImpl(avp)); } avp = prnMessage.getAvps().getAvp(AUTH_APPLICATION_ID); if (avp != null) { newMessage.getAvps().addAvp(new AvpImpl(avp)); } } // Copy proxy information { AvpSet avps = prnMessage.getAvps().getAvps(Avp.PROXY_INFO); for (Avp piAvp : avps) { newMessage.getAvps().addAvp(new AvpImpl(piAvp)); } } // Copy route information { if (newMessage.isRequest()) { if (invertPoints) { // set Dest host avp = prnMessage.getAvps().getAvp(Avp.ORIGIN_HOST); if (avp != null) { newMessage.getAvps().addAvp(new AvpImpl(Avp.DESTINATION_HOST, avp)); } // set Dest realm avp = prnMessage.getAvps().getAvp(Avp.ORIGIN_REALM); if (avp != null) { newMessage.getAvps().addAvp(new AvpImpl(Avp.DESTINATION_REALM, avp)); } } else { // set Dest host avp = prnMessage.getAvps().getAvp(Avp.DESTINATION_HOST); if (avp != null) { newMessage.getAvps().addAvp(avp); } // set Dest realm avp = prnMessage.getAvps().getAvp(Avp.DESTINATION_REALM); if (avp != null) { newMessage.getAvps().addAvp(avp); } } } // // set Orig host and realm // try { // newMessage.getAvps().addAvp(Avp.ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); // newMessage.getAvps().addAvp(Avp.ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); // } // catch (Exception e) { // logger.debug("Error copying Origin-Host/Realm AVPs", e); // } } } public static String byteArrayToHexString(byte[] in, boolean columnize) { if (in == null || in.length <= 0) { return ""; } String pseudo = "0123456789ABCDEF"; StringBuffer out = new StringBuffer(in.length * 3); for (int i = 0; i < in.length; i++) { byte ch = in[i]; out.append(pseudo.charAt((int) ((ch & 0xF0) >> 4))); out.append(pseudo.charAt((int) (ch & 0x0F))); if (columnize) { if ((i + 1) % 16 == 0) { out.append("\n"); } else if ((i + 1) % 4 == 0) { out.append(" "); } } } return out.toString(); } public static String byteArrayToHexStringLine(byte[] in) { return byteArrayToHexString(in, false); } public static String byteArrayToHexString(byte[] in) { return byteArrayToHexString(in, true); } @Override public ByteBuffer encodeMessage(IMessage message) throws ParseException { ByteArrayOutputStream out = new ByteArrayOutputStream(); try { byte[] rawData = encodeAvpSet(message.getAvps()); DataOutputStream data = new DataOutputStream(out); // Wasting processor time, are we ? // int tmp = (1 << 24) & 0xFF000000; int tmp = (1 << 24); tmp += 20 + rawData.length; data.writeInt(tmp); // Again, unneeded operation ? // tmp = (message.getFlags() << 24) & 0xFF000000; tmp = (message.getFlags() << 24); tmp += message.getCommandCode(); data.writeInt(tmp); data.write(toBytes(message.getHeaderApplicationId())); data.write(toBytes(message.getHopByHopIdentifier())); data.write(toBytes(message.getEndToEndIdentifier())); data.write(rawData); } catch (Exception e) { //logger.debug("Error during encode message", e); throw new ParseException("Failed to encode message.", e); } try { return prepareBuffer(out.toByteArray(), out.size()); } catch (AvpDataException ade) { throw new ParseException(ade); } } private byte[] toBytes(long value) { byte[] data = new byte[4]; data[0] = (byte) ((value >> 24) & 0xFF); data[1] = (byte) ((value >> 16) & 0xFF); data[2] = (byte) ((value >> 8) & 0xFF); data[3] = (byte) ((value) & 0xFF); return data; } @Override public IMessage createEmptyMessage(int commandCode, long headerAppId) { return new MessageImpl(commandCode, headerAppId); } @Override public T createEmptyMessage(Class iface, int commandCode, long headerAppId) { if (iface == IRequest.class) { return (T) new MessageImpl(commandCode, headerAppId); } return null; } public int getNextEndToEndId() { return endToEndGen.nextInt(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/RouterImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.router; import org.jdiameter.api.*; import org.jdiameter.client.api.IAnswer; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.controller.IPeerTable; import org.jdiameter.client.api.controller.IRealm; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.client.api.router.IRouter; import org.jdiameter.client.impl.helpers.AppConfiguration; import org.jdiameter.client.impl.helpers.Parameters; import org.jdiameter.client.impl.parser.MessageImpl; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.server.api.agent.IAgentConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URISyntaxException; import java.net.UnknownServiceException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import static org.jdiameter.client.impl.helpers.Parameters.*; import static org.jdiameter.server.impl.helpers.Parameters.*; /** * Diameter Routing Core * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RouterImpl implements IRouter { public static final int DONT_CACHE = 0; public static final int ALL_SESSION = 1; public static final int ALL_REALM = 2; public static final int REALM_AND_APPLICATION = 3; public static final int ALL_APPLICATION = 4; public static final int ALL_HOST = 5; public static final int ALL_USER = 6; // private static final Logger logger = LoggerFactory.getLogger(RouterImpl.class); protected MetaData metaData; // //private ConcurrentHashMap network = new ConcurrentHashMap(); protected IRealmTable realmTable; // Redirection feature public final int REDIRECT_TABLE_SIZE = 1024; //TODO: index it differently. protected List redirectTable = new ArrayList(REDIRECT_TABLE_SIZE); protected IConcurrentFactory concurrentFactory; protected IContainer container; // Answer routing feature public static int REQUEST_TABLE_SIZE = 10 * 1024; public static int REQUEST_TABLE_CLEAR_SIZE = 2 * 1024; protected Lock requestEntryTableLock = new ReentrantLock(); protected ReadWriteLock redirectTableLock = new ReentrantReadWriteLock(); //PCB added protected Map requestEntryMap; //protected List requestSortedEntryTable = new ArrayList(); protected boolean isStopped = true; public RouterImpl(IContainer container, IConcurrentFactory concurrentFactory, IRealmTable realmTable, Configuration config, MetaData aMetaData) { this.concurrentFactory = concurrentFactory; this.metaData = aMetaData; this.realmTable = realmTable; this.container = container; logger.debug("Constructor for RouterImpl: Calling loadConfiguration"); loadConfiguration(config); } protected void loadConfiguration(Configuration config) { logger.debug("Loading Router Configuration. Populating Realms, Application IDs, etc"); //add local realm : this might not be good String localRealm = config.getStringValue(OwnRealm.ordinal(), null); String localHost = config.getStringValue(Parameters.OwnDiameterURI.ordinal(), null); try { this.realmTable.addLocalRealm(localRealm, new URI(localHost).getFQDN()); } catch (UnknownServiceException use) { throw new RuntimeException("Unable to create URI from Own URI config value:" + localHost, use); } catch (URISyntaxException use) { throw new RuntimeException("Unable to create URI from Own URI config value:" + localHost, use); } if (config.getChildren(RequestTable.ordinal()) != null) { AppConfiguration requestTableConfig = (AppConfiguration) config .getChildren(org.jdiameter.server.impl.helpers.Parameters.RequestTable.ordinal())[0]; int tSize = requestTableConfig.getIntValue(RequestTableSize.ordinal(), (Integer) RequestTableSize.defValue()); int tClearSize = requestTableConfig.getIntValue(RequestTableClearSize.ordinal(), (Integer) RequestTableClearSize.defValue()); if (tSize > 0 && tClearSize >= tSize) { logger.warn( "Configuration entry RequestTable, attribute 'clear_size' [{}] should not be greater than 'size' [{}]. Adjusting.", tSize, tClearSize); while (tClearSize >= tSize) { tSize *= 10; } } REQUEST_TABLE_SIZE = tSize; REQUEST_TABLE_CLEAR_SIZE = tClearSize; } //PCB added thread safety this.requestEntryMap = new ConcurrentHashMap(REQUEST_TABLE_SIZE); logger.debug("Configured Request Table with size[{}] and clear size[{}].", REQUEST_TABLE_SIZE, REQUEST_TABLE_CLEAR_SIZE); //add realms based on realm table. if (config.getChildren(RealmTable.ordinal()) != null) { logger.debug("Going to loop through configured realms and add them into a network map"); for (Configuration items : config.getChildren(RealmTable.ordinal())) { if (items != null) { Configuration[] m = items.getChildren(RealmEntry.ordinal()); for (Configuration c : m) { try { String name = c.getStringValue(RealmName.ordinal(), ""); logger.debug("Getting config for realm [{}]", name); //Trim leading and trailing white spaces String[] hosts = Arrays.stream(c.getStringValue(RealmHosts.ordinal(), (String) RealmHosts.defValue()).split(",")) .map(String::trim) .toArray(String[]::new); logger.debug("Adding realm [{}] with hosts [{}] to network map", name, hosts); LocalAction locAction = LocalAction.valueOf(c.getStringValue(RealmLocalAction.ordinal(), "0")); boolean isDynamic = c.getBooleanValue(RealmEntryIsDynamic.ordinal(), false); long expirationTime = c.getLongValue(RealmEntryExpTime.ordinal(), 0); //check if there is Agent, ATM we support only props there. IAgentConfiguration agentConfImpl = null; Configuration[] confs = c.getChildren(Agent.ordinal()); if (confs != null && confs.length > 0) { Configuration agentConfiguration = confs[0]; //only one! agentConfImpl = this.container.getAssemblerFacility() .getComponentInstance(IAgentConfiguration.class); if (agentConfImpl != null) { agentConfImpl = agentConfImpl.parse(agentConfiguration); } } Configuration[] apps = c.getChildren(ApplicationId.ordinal()); if (apps != null) { for (Configuration a : apps) { ApplicationId appId = null; if (a != null) { long vnd = a.getLongValue(VendorId.ordinal(), 0); long auth = a.getLongValue(AuthApplId.ordinal(), 0); long acc = a.getLongValue(AcctApplId.ordinal(), 0); if (auth != 0) { appId = org.jdiameter.api.ApplicationId.createByAuthAppId(vnd, auth); } else { appId = org.jdiameter.api.ApplicationId.createByAccAppId(vnd, acc); } if (logger.isDebugEnabled()) { logger.debug("Realm [{}] has application Acct [{}] Auth [{}] Vendor [{}]", new Object[]{name, appId.getAcctAppId(), appId.getAuthAppId(), appId.getVendorId()}); } } this.realmTable.addRealm(name, appId, locAction, agentConfImpl, isDynamic, expirationTime, hosts); } } else { this.realmTable.addRealm(name, null, locAction, agentConfImpl, isDynamic, expirationTime, hosts); } } catch (Exception e) { logger.warn("Unable to append realm entry", e); } } } } } } @Override public void registerRequestRouteInfo(IRequest request) { logger.debug("Entering registerRequestRouteInfo"); if (REQUEST_TABLE_SIZE == 0) { return; // we don't have anything to do as we are storing routing info at answer message } try { // PCB removed lock // requestEntryTableLock.writeLock().lock(); long hopByHopId = request.getHopByHopIdentifier(); Avp hostAvp = request.getAvps().getAvp(Avp.ORIGIN_HOST); // we store the peer FQDN instead of Origin-Host as we want to route back to it, in case of proxied requests this // should be the FQDN of the proxy, otherwise it's (should be) the same as Origin-Host String host = ((IMessage) request).getPeer() != null ? ((IMessage) request).getPeer().getUri().getFQDN() : hostAvp.getDiameterIdentity(); Avp realmAvp = request.getAvps().getAvp(Avp.ORIGIN_REALM); AnswerEntry entry; AvpSet rrAvps = request.getAvps().getAvps(Avp.ROUTE_RECORD); if (rrAvps.size() > 0) { logger.debug("Found [{}] Route-Record AVP(s) in Request with HbH [{}], storing them for copying and routing.", rrAvps.size(), request.getHopByHopIdentifier()); ArrayList rrStrings = new ArrayList(); for (Avp rrAvp : rrAvps) { String rrAvpHost = rrAvp.getDiameterIdentity(); logger.trace("Route-Record in Request with HbH [{}]: [{}]", request.getHopByHopIdentifier(), rrAvpHost); rrStrings.add(rrAvpHost); } entry = new AnswerEntry(hopByHopId, host, realmAvp != null ? realmAvp.getDiameterIdentity() : null, rrStrings); } else { entry = new AnswerEntry(hopByHopId, host, realmAvp != null ? realmAvp.getDiameterIdentity() : null); } int s = requestEntryMap.size(); // PCB added logging logger.debug("RequestRoute map size is [{}]", s); //PCB added if (s > REQUEST_TABLE_CLEAR_SIZE) { try { requestEntryTableLock.lock(); s = requestEntryMap.size(); logger.debug("After 'lock', RequestRoute map size is [{}]", s); // The double-check with a gap is in case while about to clear the map, it drops below REQUEST_TABLE_SIZE due to a // response being sent, and then the lock might not be in effect for another thread // Hence lock at REQUEST_TABLE_CLEAR_SIZE and clear at REQUEST_TABLE_SIZE so that all threads would be locked not // just the first to reach REQUEST_TABLE_SIZE if (s > REQUEST_TABLE_SIZE) { // Going to clear it out and suffer the consequences of some messages possibly not being routed back the clients.. logger.warn("RequestRoute map size is [{}]. There's probably a leak. Cleaning up after a short wait...", s); // Lets do our best to avoid lost messages by locking table from writes (as this is the only code writing to it), // sleeping for a while for responses to be sent and then clearing it Thread.sleep(5000); logger.warn("RequestRoute map size is now [{}] after sleeping. Clearing it!", requestEntryMap.size()); requestEntryMap.clear(); } } catch (Exception e) { logger.warn("Failure trying to clear RequestRoute map", e); } finally { requestEntryTableLock.unlock(); } } String messageKey = makeRoutingKey(request); logger.debug( "Adding request key [{}] to RequestRoute map with entry [{}] for routing answers back to the requesting peer", messageKey, entry); requestEntryMap.put(messageKey, entry); // requestSortedEntryTable.add(hopByHopId); } catch (Exception e) { logger.warn("Unable to store route info", e); } finally { // requestEntryTableLock.writeLock().unlock(); } } // PCB - Made better routing algorithm that should not grow all the time private String makeRoutingKey(Message message) { String sessionId = message.getSessionId(); return new StringBuilder(sessionId != null ? sessionId : "null").append(message.getEndToEndIdentifier()) .append(message.getHopByHopIdentifier()).toString(); } private String[] getRequestRouteInfoAndCopyProxyAvps(IMessage message, boolean copy) { if (REQUEST_TABLE_SIZE == 0) { return ((MessageImpl) message).getRoutingInfo(); // using answer stored routing info // TODO: Handle copy Proxy AVPs in this case... } // using request table String messageKey = makeRoutingKey(message); AnswerEntry ans = requestEntryMap.get(messageKey); if (ans != null) { if (logger.isDebugEnabled()) { logger.debug("getRequestRouteInfo found host [{}] and realm [{}] for Message key Id [{}]", new Object[]{ans.getHost(), ans.getRealm(), messageKey}); } if (ans.getRouteRecords() != null && ans.getRouteRecords().size() > 0) { AvpSet msgRouteRecords = message.getAvps().getAvps(Avp.ROUTE_RECORD); if (msgRouteRecords.size() > 0) { logger.debug("We had Route-Records to insert but the message already has some... not doing anything"); } else { for (String rr : ans.getRouteRecords()) { message.getAvps().addAvp(Avp.ROUTE_RECORD, rr, true); } } } return new String[]{ans.getHost(), ans.getRealm()}; } else { if (logger.isWarnEnabled()) { logger.warn("Could not find route info for message key [{}]. Table size is [{}]", messageKey, requestEntryMap.size()); } return null; } } @Override public String[] getRequestRouteInfo(IMessage message) { return getRequestRouteInfoAndCopyProxyAvps(message, false); } //PCB added @Override public void garbageCollectRequestRouteInfo(IMessage message) { if (REQUEST_TABLE_SIZE == 0) { return; // we don't have anything to do as we are storing routing info at answer message } String messageKey = makeRoutingKey(message); requestEntryMap.remove(messageKey); } @Override public IPeer getPeer(IMessage message, IPeerTable manager) throws RouteException, AvpDataException { logger.debug("Getting a peer for message [{}]", message); //FIXME: add ability to send without matching realm+peer pair?, that is , route based on peer table entries? //that is, if msg.destHost != null > getPeer(msg.destHost).sendMessage(msg); String destRealm = null; String destHost = null; IRealm matchedRealm = null; String[] info = null; // Get destination information if (message.isRequest()) { Avp avpRealm = message.getAvps().getAvp(Avp.DESTINATION_REALM); if (avpRealm == null) { throw new RouteException("Destination realm avp is empty"); } destRealm = avpRealm.getDiameterIdentity(); Avp avpHost = message.getAvps().getAvp(Avp.DESTINATION_HOST); if (avpHost != null) { destHost = avpHost.getDiameterIdentity(); } if (logger.isDebugEnabled()) { logger.debug("Looking up peer for request: [{}], DestHost=[{}], DestRealm=[{}]", new Object[]{message, destHost, destRealm}); } matchedRealm = (IRealm) this.realmTable.matchRealm(message); } else { //answer, search info = getRequestRouteInfoAndCopyProxyAvps(message, true); if (info != null) { destHost = info[0]; destRealm = info[1]; logger.debug("Message is an answer. Host is [{}] and Realm is [{}] as per hopbyhop info from request", destHost, destRealm); if (destRealm == null) { logger.warn("Destination-Realm was null for hopbyhop id " + message.getHopByHopIdentifier()); } } else { logger.debug("No Host and realm found based on hopbyhop id of the answer associated request"); } //FIXME: if no info, should not send it ? //FIXME: add strict deff in route back table so stack does not have to lookup? if (logger.isDebugEnabled()) { logger.debug("Looking up peer for answer: [{}], DestHost=[{}], DestRealm=[{}]", new Object[]{message, destHost, destRealm}); } matchedRealm = (IRealm) this.realmTable.matchRealm((IAnswer) message, destRealm); } // IPeer peer = getPeerPredProcessing(message, destRealm, destHost); // // if (peer != null) { // logger.debug("Found during preprocessing...[{}]", peer); // return peer; // } // Check realm name if (matchedRealm == null) { if (message.getAvps().getAvp(Avp.ROUTE_RECORD) == null) { // if it doesn't come through a proxy, we fail with unknown realm... throw new RouteException("Unknown realm name [" + destRealm + "]"); } else { logger.debug( "Realm [{}] not found, but message has Route-Record AVP so it came from proxy peer [{}]. Proceeding...", destRealm, destHost); } } // THIS IS GET PEER, NOT ROUTE!!!!!!! // Redirect processing //redirectProcessing(message, destRealm, destHost); // Check previous context information, this takes care of most answers. if (message.getPeer() != null && destHost != null && destHost.equals(message.getPeer().getUri().getFQDN()) && message.getPeer().hasValidConnection()) { if (logger.isDebugEnabled()) { logger.debug("Select previous message usage peer [{}]", message.getPeer()); } return message.getPeer(); } // Balancing procedure IPeer c = destHost != null ? manager.getPeer(destHost) : null; if (c != null && c.hasValidConnection()) { logger.debug("Found a peer using destination host avp [{}] peer is [{}] with a valid connection.", destHost, c); //here matchedRealm MAY return c; } else { logger.debug( "Finding peer by destination host avp [host={}] did not find anything. Now going to try finding one by destination realm [{}]", destHost, destRealm); String[] peers = matchedRealm.getPeerNames(); if (peers == null || peers.length == 0) { throw new RouteException("Unable to find context by route information [" + destRealm + " ," + destHost + "]"); } // Collect peers ArrayList availablePeers = new ArrayList(5); logger.debug("Looping through peers in realm [{}]", destRealm); for (String peerName : peers) { IPeer localPeer = manager.getPeer(peerName); if (logger.isDebugEnabled()) { logger.debug("Checking peer [{}] for name [{}]", new Object[]{localPeer, peerName}); } // ammendonca: added peer state check.. should not be needed but // hasValidConnection is returning true for disconnected peers in *FTFlowTests if (localPeer != null && localPeer.getState(PeerState.class) == PeerState.OKAY) { if (localPeer.hasValidConnection()) { if (logger.isDebugEnabled()) { logger.debug( "Found available peer to add to available peer list with uri [{}] with a valid connection", localPeer.getUri().toString()); } availablePeers.add(localPeer); } else { if (logger.isDebugEnabled()) { logger.debug("Found a peer with uri [{}] with no valid connection", localPeer.getUri()); } } } } if (logger.isDebugEnabled()) { logger.debug("Performing Realm routing. Realm [{}] has the following peers available [{}] from list [{}]", new Object[]{destRealm, availablePeers, Arrays.asList(peers)}); } // Balancing IPeer peer = selectPeer(availablePeers); if (peer == null) { throw new RouteException( "Unable to find valid connection to peer[" + destHost + "] in realm[" + destRealm + "]"); } else { if (logger.isDebugEnabled()) { logger.debug("Load balancing selected peer with uri [{}]", peer.getUri()); } } return peer; } } @Override public IRealmTable getRealmTable() { return this.realmTable; } @Override public void processRedirectAnswer(IRequest request, IAnswer answer, IPeerTable table) throws InternalException, RouteException { try { Avp destinationRealmAvp = request.getAvps().getAvp(Avp.DESTINATION_REALM); if (destinationRealmAvp == null) { throw new RouteException("Request to be routed has no Destination-Realm AVP!"); // sanity check... if user messes with us } String destinationRealm = destinationRealmAvp.getDiameterIdentity(); String[] redirectHosts = null; if (answer.getAvps().getAvps(Avp.REDIRECT_HOST) != null) { AvpSet avps = answer.getAvps().getAvps(Avp.REDIRECT_HOST); redirectHosts = new String[avps.size()]; int i = 0; // loop detected for (Avp avp : avps) { String r = avp.getDiameterIdentity(); if (r.equals(metaData.getLocalPeer().getUri().getFQDN())) { throw new RouteException("Loop detected"); } redirectHosts[i++] = r; } } // int redirectUsage = DONT_CACHE; Avp redirectHostUsageAvp = answer.getAvps().getAvp(Avp.REDIRECT_HOST_USAGE); if (redirectHostUsageAvp != null) { redirectUsage = redirectHostUsageAvp.getInteger32(); } if (redirectUsage != DONT_CACHE) { long redirectCacheTime = 0; Avp redirectCacheMaxTimeAvp = answer.getAvps().getAvp(Avp.REDIRECT_MAX_CACHE_TIME); if (redirectCacheMaxTimeAvp != null) { redirectCacheTime = redirectCacheMaxTimeAvp.getUnsigned32(); } String primaryKey = null; ApplicationId secondaryKey = null; switch (redirectUsage) { case ALL_SESSION: primaryKey = request.getSessionId(); break; case ALL_REALM: primaryKey = destinationRealm; break; case REALM_AND_APPLICATION: primaryKey = destinationRealm; secondaryKey = ((IMessage) request).getSingleApplicationId(); break; case ALL_APPLICATION: secondaryKey = ((IMessage) request).getSingleApplicationId(); break; case ALL_HOST: Avp destinationHostAvp = request.getAvps().getAvp(Avp.DESTINATION_HOST); if (destinationHostAvp == null) { throw new RouteException("Request to be routed has no Destination-Host AVP!"); // sanity check... if user messes with us } primaryKey = destinationHostAvp.getDiameterIdentity(); break; case ALL_USER: Avp userNameAvp = answer.getAvps().getAvp(Avp.USER_NAME); if (userNameAvp == null) { throw new RouteException("Request to be routed has no User-Name AVP!"); // sanity check... if user messes with us } primaryKey = userNameAvp.getUTF8String(); break; } // if (redirectTable.size() > REDIRECT_TABLE_SIZE) { try { //yes, possible that this will trigger this procedure twice, but thats worst than locking always. redirectTableLock.writeLock().lock(); trimRedirectTable(); } finally { redirectTableLock.writeLock().unlock(); } } if (REDIRECT_TABLE_SIZE > redirectTable.size()) { RedirectEntry e = new RedirectEntry(primaryKey, secondaryKey, redirectCacheTime, redirectUsage, redirectHosts, destinationRealm); redirectTable.add(e); //redirectProcessing(answer, destRealm.getOctetString(), destHost !=null ? destHost.getOctetString():null); //we dont have to elect? updateRoute(request, e.getRedirectHost()); } else { if (redirectHosts != null && redirectHosts.length > 0) { String destHost = redirectHosts[0]; //setRouteInfo(answer, getRealmForPeer(destHost), destHost); updateRoute(request, destHost); } } } else { if (redirectHosts != null && redirectHosts.length > 0) { String destHost = redirectHosts[0]; //setRouteInfo(answer, getRealmForPeer(destHost), destHost); updateRoute(request, destHost); } } //now send table.sendMessage((IMessage) request); } catch (AvpDataException exc) { throw new InternalException(exc); } catch (IllegalDiameterStateException e) { throw new InternalException(e); } catch (IOException e) { throw new InternalException(e); } } /** * */ private void trimRedirectTable() { for (int index = 0; index < redirectTable.size(); index++) { try { if (redirectTable.get(index).getExpiredTime() <= System.currentTimeMillis()) { redirectTable.remove(index); index--; //a trick :) } } catch (Exception e) { logger.debug("Error in redirect task cleanup.", e); break; } } } /** * @param request * @param destHost */ private void updateRoute(IRequest request, String destHost) { // Realm does not change I think... :) request.getAvps().removeAvp(Avp.DESTINATION_HOST); request.getAvps().addAvp(Avp.DESTINATION_HOST, destHost, true, false, true); } @Override public boolean updateRoute(IRequest message) throws RouteException, AvpDataException { AvpSet set = message.getAvps(); Avp destRealmAvp = set.getAvp(Avp.DESTINATION_REALM); Avp destHostAvp = set.getAvp(Avp.DESTINATION_HOST); if (destRealmAvp == null) { throw new RouteException("Request does not have Destination-Realm AVP!"); } String destRealm = destRealmAvp.getDiameterIdentity(); String destHost = destHostAvp != null ? destHostAvp.getDiameterIdentity() : null; boolean matchedEntry = false; String userName = null; // get Session id String sessionId = message.getSessionId(); // Avp avpUserName = message.getAvps().getAvp(Avp.USER_NAME); // Get application id ApplicationId appId = ((IMessage) message).getSingleApplicationId(); // User name if (avpUserName != null) { userName = avpUserName.getUTF8String(); } // Processing table try { redirectTableLock.readLock().lock(); for (int index = 0; index < redirectTable.size(); index++) { RedirectEntry e = redirectTable.get(index); switch (e.getUsageType()) { case ALL_SESSION: // Usage type: ALL SESSION matchedEntry = sessionId != null && e.primaryKey != null & sessionId.equals(e.primaryKey); break; case ALL_REALM: // Usage type: ALL REALM matchedEntry = destRealm != null && e.primaryKey != null & destRealm.equals(e.primaryKey); break; case REALM_AND_APPLICATION: // Usage type: REALM AND APPLICATION matchedEntry = destRealm != null & appId != null & e.primaryKey != null & e.secondaryKey != null & destRealm.equals(e.primaryKey) & appId.equals(e.secondaryKey); break; case ALL_APPLICATION: // Usage type: ALL APPLICATION matchedEntry = appId != null & e.secondaryKey != null & appId.equals(e.secondaryKey); break; case ALL_HOST: // Usage type: ALL HOST matchedEntry = destHost != null & e.primaryKey != null & destHost.equals(e.primaryKey); break; case ALL_USER: // Usage type: ALL USER matchedEntry = userName != null & e.primaryKey != null & userName.equals(e.primaryKey); break; } // Update message redirect information if (matchedEntry) { String newDestHost = e.getRedirectHost(); //String newDestRealm = getRealmForPeer(destHost); //setRouteInfo(message, destRealm, newDestHost); updateRoute(message, newDestHost); logger.debug("Redirect message from host={}; to new-host={}, realm={} ", new Object[]{destHost, newDestHost, destRealm}); return true; } } } finally { redirectTableLock.readLock().unlock(); } return false; } protected IPeer getPeerPredProcessing(IMessage message, String destRealm, String destHost) { return null; } @Override public void start() { if (isStopped) { //redirectScheduler = concurrentFactory.getScheduledExecutorService(RedirectMessageTimer.name()); //redirectEntryHandler = redirectScheduler.scheduleAtFixedRate(redirectTask, 1, 1, TimeUnit.SECONDS); isStopped = false; } } @Override public void stop() { isStopped = true; // if (redirectEntryHandler != null) { // redirectEntryHandler.cancel(true); //} if (redirectTable != null) { redirectTable.clear(); } if (requestEntryMap != null) { requestEntryMap.clear(); } //PCB removed //if (requestSortedEntryTable != null) { // requestSortedEntryTable.clear(); //} //if (redirectScheduler != null) { // concurrentFactory.shutdownNow(redirectScheduler); //} } @Override public void destroy() { try { if (!isStopped) { stop(); } } catch (Exception exc) { logger.error("Unable to stop router", exc); } //redirectEntryHandler = null; //redirectScheduler = null; redirectTable = null; requestEntryMap = null; } protected IPeer selectPeer(List availablePeers) { IPeer p = null; for (IPeer c : availablePeers) { if (p == null || c.getRating() >= p.getRating()) { p = c; } } return p; } // protected void redirectProcessing(IMessage message, final String destRealm, final String destHost) throws AvpDataException { // String userName = null; // // get Session id // String sessionId = message.getSessionId(); // // // Avp avpUserName = message.getAvps().getAvp(Avp.USER_NAME); // // Get application id // ApplicationId appId = message.getSingleApplicationId(); // // User name // if (avpUserName != null) // userName = avpUserName.getUTF8String(); // // Processing table // for (RedirectEntry e : redirectTable.values()) { // boolean matchedEntry = false; // switch (e.getUsageType()) { // case ALL_SESSION: // Usage type: ALL SESSION // matchedEntry = sessionId != null && e.primaryKey != null & // sessionId.equals(e.primaryKey); // break; // case ALL_REALM: // Usage type: ALL REALM // matchedEntry = destRealm != null && e.primaryKey != null & // destRealm.equals(e.primaryKey); // break; // case REALM_AND_APPLICATION: // Usage type: REALM AND APPLICATION // matchedEntry = destRealm != null & appId != null & e.primaryKey != null & e.secondaryKey != null & // destRealm.equals(e.primaryKey) & appId.equals(e.secondaryKey); // break; // case ALL_APPLICATION: // Usage type: ALL APPLICATION // matchedEntry = appId != null & e.secondaryKey != null & // appId.equals(e.secondaryKey); // break; // case ALL_HOST: // Usage type: ALL HOST // matchedEntry = destHost != null & e.primaryKey != null & // destHost.equals(e.primaryKey); // break; // case ALL_USER: // Usage type: ALL USER // matchedEntry = userName != null & e.primaryKey != null & // userName.equals(e.primaryKey); // break; // } // // Update message redirect information // if (matchedEntry) { // String newDestHost = e.getRedirectHost(); // // FIXME: Alexandre: Should use newDestHost? // String newDestRealm = getRealmForPeer(destHost); // setRouteInfo(message, destRealm, newDestHost); // logger.debug("Redirect message from host={}; realm={} to new-host={}; new-realm={}", // new Object[] {destHost, destRealm, newDestHost, newDestRealm}); // return; // } // } // } // // private void setRouteInfo(IMessage message, String destRealm, String destHost) { // message.getAvps().removeAvp(Avp.DESTINATION_REALM); // message.getAvps().removeAvp(Avp.DESTINATION_HOST); // if (destRealm != null) // message.getAvps().addAvp(Avp.DESTINATION_REALM, destRealm, true, false, true); // if (destHost != null) // message.getAvps().addAvp(Avp.DESTINATION_HOST, destHost, true, false, true); // } //does not make sense, there can be multple realms :/ // public String getRealmForPeer(String destHost) { // for (String key : getRealmsName()) { // for (String h : getRealmPeers(key)) { // if (h.trim().equals(destHost.trim())) // return key; // } // } // return null; // } protected class RedirectEntry { final long createTime = System.currentTimeMillis(); String primaryKey; ApplicationId secondaryKey; long liveTime; int usageType; String[] hosts; String destinationRealm; public RedirectEntry(String key1, ApplicationId key2, long time, int usage, String[] aHosts, String destinationRealm) throws InternalError { // Check arguments if (key1 == null && key2 == null) { throw new InternalError("Incorrect redirection key."); } if (aHosts == null || aHosts.length == 0) { throw new InternalError("Incorrect redirection hosts."); } // Set values this.primaryKey = key1; this.secondaryKey = key2; this.liveTime = time * 1000; this.usageType = usage; this.hosts = aHosts; this.destinationRealm = destinationRealm; } public int getUsageType() { return usageType; } public String[] getRedirectHosts() { return hosts; } public String getRedirectHost() { return hosts[hosts.length - 1]; } public long getExpiredTime() { return createTime + liveTime; } @Override public int hashCode() { int result = (primaryKey != null ? primaryKey.hashCode() : 0); result = 31 * result + (secondaryKey != null ? secondaryKey.hashCode() : 0); result = 31 * result + (int) (liveTime ^ (liveTime >>> 32)); result = 31 * result + usageType; result = 31 * result + (hosts != null ? hosts.hashCode() : 0); return result; } @Override public boolean equals(Object other) { if (other == this) { return true; } if (other instanceof RedirectEntry) { RedirectEntry that = (RedirectEntry) other; return liveTime == that.liveTime && usageType == that.usageType && Arrays.equals(hosts, that.hosts) && !(primaryKey != null ? !primaryKey.equals(that.primaryKey) : that.primaryKey != null) && !(secondaryKey != null ? !secondaryKey.equals(that.secondaryKey) : that.secondaryKey != null); } else { return false; } } } protected class AnswerEntry { final long createTime = System.nanoTime(); Long hopByHopId; String host, realm; ArrayList routeRecords; public AnswerEntry(Long hopByHopId) { this.hopByHopId = hopByHopId; } public AnswerEntry(Long hopByHopId, String host, String realm) throws InternalError { this.hopByHopId = hopByHopId; this.host = host; this.realm = realm; } public AnswerEntry(Long hopByHopId, String host, String realm, ArrayList routeRecords) throws InternalError { this.hopByHopId = hopByHopId; this.host = host; this.realm = realm; this.routeRecords = routeRecords; } public long getCreateTime() { return createTime; } public Long getHopByHopId() { return hopByHopId; } public String getHost() { return host; } public String getRealm() { return realm; } public ArrayList getRouteRecords() { return routeRecords; } @Override public int hashCode() { return super.hashCode(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } AnswerEntry that = (AnswerEntry) o; return hopByHopId == that.hopByHopId; } @Override public String toString() { return "AnswerEntry {" + "createTime=" + createTime + ", hopByHopId=" + hopByHopId + ", host=" + host + ", realm=" + realm + "}"; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/WeightedLeastConnectionsRouter.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.router; import java.util.Arrays; import java.util.List; import org.jdiameter.api.Configuration; import org.jdiameter.api.MetaData; import org.jdiameter.api.PeerState; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.jdiameter.server.api.IRouter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Weighted Least-Connections router implementation
      *
      *

      * This requires that {@link IStatistic Statistics} for the following records are enabled: * Peer,AppGenRequestPerSecond,NetGenRequestPerSecond In the client configuration, please use the following settings: * *

       *   ...
       *   
       *    
       *   
       *   ...
       *   
       *   
       *   
       * 
      * * @author Nils Sowen * @see http://kb.linuxvirtualserver.org/wiki/Weighted_Least-Connection_Scheduling */ @SuppressWarnings("all") //3rd party lib public class WeightedLeastConnectionsRouter extends RouterImpl implements IRouter { private static final Logger logger = LoggerFactory.getLogger(WeightedLeastConnectionsRouter.class); protected WeightedLeastConnectionsRouter(IRealmTable table, Configuration config) { super(null, null, table, config, null); } public WeightedLeastConnectionsRouter(IContainer container, IConcurrentFactory concurrentFactory, IRealmTable realmTable, Configuration config, MetaData aMetaData) { super(container, concurrentFactory, realmTable, config, aMetaData); } /** * Return peer with least connections
      * {@url http://kb.linuxvirtualserver.org/wiki/Weighted_Least-Connection_Scheduling * http://kb.linuxvirtualserver.org/wiki/Weighted_Least-Connection_Scheduling} * *

      * The weighted least-connection scheduling is a superset of the least-connection scheduling, in which you can * assign a performance weight to each real server. The servers with a higher weight value will receive a larger * percentage of active connections at any one time. The default server weight is one, and the IPVS Administrator or * monitoring program can assign any weight to real server. In the weighted least-connections scheduling, new * network connection is assigned to a server which has the least ratio of the current active connection number to * its weight. *

      * Supposing there is a server set S = {S0, S1, ..., Sn-1}, W(Si) is the weight of server Si; C(Si) is the current * connection number of server Si; CSUM = ΣC(Si) (i=0, 1, .. , n-1) is the sum of current connection numbers; *

      * The new connection is assigned to the server j, in which (C(Sm) / CSUM)/ W(Sm) = min { (C(Si) / CSUM) / W(Si)} * (i=0, 1, . , n-1), where W(Si) isn't zero Since the CSUM is a constant in this lookup, there is no need to divide * by CSUM, the condition can be optimized as C(Sm) / W(Sm) = min { C(Si) / W(Si)} (i=0, 1, . , n-1), where W(Si) * isn't zero *

      * Since division operation eats much more CPU cycles than multiply operation, and Linux does not allow float mode * inside the kernel, the condition C(Sm)/W(Sm) > C(Si)/W(Si) can be optimized as C(Sm)*W(Si) > C(Si)*W(Sm). The * scheduling should guarantee that a server will not be scheduled when its weight is zero. Therefore, the pseudo * code of weighted least-connection scheduling algorithm is *

      * *

           * {@code
           * for (m = 0; m < n; m++) {
           *     if (W(Sm) > 0) {
           *         for (i = m + 1; i < n; i++) {
           *             if (C(Sm) * W(Si) > C(Si) * W(Sm))
           *                 m = i;
           *         }
           *         return Sm;
           *     }
           * }
           * return NULL;
           * }
           * 
      *

      * The weighted least-connection scheduling algorithm requires additional division than the least-connection * scheduling. In a hope to minimize the overhead of scheduling when servers have the same processing capacity, both * the least-connection scheduling and the weighted least-connection scheduling algorithms are implemented. * * @param availablePeers list of peers that are in {@link PeerState#OKAY OKAY} state * * @return the selected peer according to algorithm * * @see http://kb.linuxvirtualserver.org/wiki/Weighted_Least-Connection_Scheduling */ @Override public IPeer selectPeer(List availablePeers) { int peerSize = availablePeers != null ? availablePeers.size() : 0; // Return none if empty, or first if only one member found if (peerSize <= 0) { return null; } if (peerSize == 1) { return availablePeers.iterator().next(); } for (int m = 0; m < peerSize; peerSize++) { IPeer peerM = availablePeers.get(m); if (peerM.getRating() > 0) { for (int i = m + 1; i < peerSize; i++) { IPeer peerI = availablePeers.get(i); if (getNumConnections(peerM) * peerI.getRating() > getNumConnections(peerI) * peerM.getRating()) { m = i; } } return availablePeers.get(m); } } // Return first peer if anything did go wrong return availablePeers.iterator().next(); } /** * Since num connections is not available, determine throughput by reading statistics and assume the load of the * peer * * @param peer * * @return throughput indicator */ protected long getNumConnections(IPeer peer) { if (peer == null) { return 0; } IStatistic stats = peer.getStatistic(); // If no statistics are available, return zero if (!stats.isEnabled()) { if (logger.isDebugEnabled()) { logger.debug("Statistics for peer are disabled. Please enable statistics in client config"); } return 0; } // Requests per second initiated by Local Peer + Request initiated by Remote peer String uri = peer.getUri() == null ? "local" : peer.getUri().toString(); long requests = getRecord(IStatisticRecord.Counters.AppGenRequestPerSecond.name() + '.' + uri, stats) + getRecord(IStatisticRecord.Counters.NetGenRequestPerSecond.name() + '.' + uri, stats); // There are likely more requests than responses active long connections = Math.max(0, requests); if (logger.isTraceEnabled()) { logger.trace("Active connections for {}: {}", peer, connections); } return connections; } /** * Return statistics record value from given {@link IStatistic} * * @param record key to retrieve * @param stats statistic object * * @return */ protected long getRecord(String record, IStatistic stats) { if (record == null || stats == null) { return 0; } IStatisticRecord statsRecord = stats.getRecordByName(record); if (statsRecord == null) { if (logger.isDebugEnabled()) { logger.debug("Warning: no record for {}, available: {}", record, Arrays.toString(stats.getRecords())); } return 0; } return statsRecord.getValueAsLong(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/router/WeightedRoundRobinRouter.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.router; import java.util.List; import org.jdiameter.api.Configuration; import org.jdiameter.api.MetaData; import org.jdiameter.api.PeerState; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.server.api.IRouter; /** * Weighted round-robin router implementation * * @author Nils Sowen * @see http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling */ @SuppressWarnings("all") //3rd party lib public class WeightedRoundRobinRouter extends RouterImpl implements IRouter { private int lastSelectedPeer = -1; private int currentWeight = 0; protected WeightedRoundRobinRouter(IRealmTable table, Configuration config) { super(null, null, table, config, null); } public WeightedRoundRobinRouter(IContainer container, IConcurrentFactory concurrentFactory, IRealmTable realmTable, Configuration config, MetaData aMetaData) { super(container, concurrentFactory, realmTable, config, aMetaData); } /** * Select peer by weighted round-robin scheduling As documented in * http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling * *

      * The weighted round-robin scheduling is designed to better handle servers with different processing capacities. * Each server can be assigned a weight, an integer value that indicates the processing capacity. Servers with * higher weights receive new connections first than those with less weights, and servers with higher weights get * more connections than those with less weights and servers with equal weights get equal connections. The pseudo * code of weighted round-robin scheduling is as follows: *

      * Supposing that there is a server set S = {S0, S1, …, Sn-1}; W(Si) indicates the weight of Si; i indicates the * server selected last time, and i is initialized with -1; cw is the current weight in scheduling, and cw is * initialized with zero; max(S) is the maximum weight of all the servers in S; gcd(S) is the greatest common * divisor of all server weights in S; *

      * *

           * {@code
           *   while (true) {
           *   i = (i + 1) mod n;
           *   if (i == 0) {
           *     cw = cw - gcd(S);
           *     if (cw <= 0) {
           *       cw = max(S);
           *       if (cw == 0)
           *       return NULL;
           *     }
           *   }
           *   if (W(Si) >= cw)
           *     return Si;
           *   }
           * }
           * 
      *

      * For example, the real servers, A, B and C, have the weights, 4, 3, 2 respectively, a scheduling sequence will be * AABABCABC in a scheduling period (mod sum(Wi)). *

      * In an optimized implementation of the weighted round-robin scheduling, a scheduling sequence will be generated * according to the server weights after the rules of IPVS are modified. The network connections are directed to the * different real servers based on the scheduling sequence in a round-robin manner. *

      * The weighted round-robin scheduling is better than the round-robin scheduling, when the processing capacity of * real servers are different. However, it may lead to dynamic load imbalance among the real servers if the load of * the requests vary highly. In short, there is the possibility that a majority of requests requiring large * responses may be directed to the same real server. *

      * Actually, the round-robin scheduling is a special instance of the weighted round-robin scheduling, in which all * the weights are equal. *

      * This method is internally synchronized due to concurrent modifications to lastSelectedPeer and currentWeight. * Please consider this when relying on heavy throughput. *

      * Please note: if the list of availablePeers changes between calls (e.g. if a peer becomes active or inactive), the * balancing algorithm is disturbed and might be distributed uneven. This is likely to happen if peers are * flapping. * * @param availablePeers list of peers that are in {@link PeerState#OKAY OKAY} state * * @return the selected peer according to algorithm * * @see http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling */ @Override public IPeer selectPeer(List availablePeers) { int peerSize = availablePeers != null ? availablePeers.size() : 0; // Return none if empty, or first if only one member found if (peerSize <= 0) { return null; } if (peerSize == 1) { return availablePeers.iterator().next(); } // Find maximum weight and greatest common divisor of weight across all peers int maxWeight = 0; Integer gcd = null; for (IPeer peer : availablePeers) { maxWeight = Math.max(maxWeight, peer.getRating()); gcd = (gcd == null) ? peer.getRating() : gcd(gcd, peer.getRating()); } // Find best matching candidate. Synchronized here due to consistent changes on member variables synchronized (this) { for (;;) { lastSelectedPeer = (lastSelectedPeer + 1) % peerSize; if (lastSelectedPeer == 0) { currentWeight = currentWeight - gcd; if (currentWeight <= 0) { currentWeight = maxWeight; } } if (peerSize <= lastSelectedPeer) { lastSelectedPeer = -1; // safety first, restart if peer size has accidentally changed. continue; } IPeer candidate = availablePeers.get(lastSelectedPeer); if (candidate.getRating() >= currentWeight) { return availablePeers.get(lastSelectedPeer); } } } } /** * Return greatest common divisor for two integers * https://en.wikipedia.org/wiki/Greatest_common_divisor#Using_Euclid.27s_algorithm * * @param a * @param b * * @return greatest common divisor */ protected int gcd(int a, int b) { return (b == 0) ? a : gcd(b, a % b); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/TransportLayerFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.transport; import static java.lang.Class.forName; import java.lang.reflect.Constructor; import java.net.InetAddress; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.client.api.io.IConnection; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.ITransportLayerFactory; import org.jdiameter.client.api.io.TransportError; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.helpers.AppConfiguration; import org.jdiameter.client.impl.helpers.ExtensionPoint; import org.jdiameter.client.impl.helpers.Parameters; import org.jdiameter.common.api.concurrent.DummyConcurrentFactory; import org.jdiameter.common.api.concurrent.IConcurrentFactory; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class TransportLayerFactory implements ITransportLayerFactory { private Class connectionClass; private Constructor constructorIAi, constructorIAiCL; protected IMessageParser parser; protected Configuration config = null; public TransportLayerFactory(Configuration config, IMessageParser parser) throws TransportException { this.config = config; Configuration[] children = config.getChildren(Parameters.Extensions.ordinal()); AppConfiguration internalExtensions = (AppConfiguration) children[ExtensionPoint.Internal.id()]; String implName = internalExtensions.getStringValue( ExtensionPoint.InternalConnectionClass.ordinal(), ExtensionPoint.InternalConnectionClass.defValue()); try { //TODO: this should be enough to check if class has interface!? this.connectionClass = (Class) forName(implName); if (!IConnection.class.isAssignableFrom(this.connectionClass)) { throw new TransportException("Specified class does not inherit IConnection interface " + this.connectionClass, TransportError.Internal); } } catch (Exception e) { throw new TransportException("Cannot prepare specified connection class " + this.connectionClass, TransportError.Internal, e); } try { //TODO: this is bad practice, IConnection is interface and this code enforces constructor type to be present! constructorIAiCL = connectionClass.getConstructor( Configuration.class, IConcurrentFactory.class, InetAddress.class, Integer.TYPE, InetAddress.class, Integer.TYPE, IConnectionListener.class, IMessageParser.class, String.class); constructorIAi = connectionClass.getConstructor( Configuration.class, IConcurrentFactory.class, InetAddress.class, Integer.TYPE, InetAddress.class, Integer.TYPE, IMessageParser.class, String.class); } catch (Exception e) { throw new TransportException("Cannot find required constructor", TransportError.Internal, e); } this.parser = parser; } @Override public IConnection createConnection(InetAddress remoteAddress, IConcurrentFactory factory, int remotePort, InetAddress localAddress, int localPort, String ref) throws TransportException { try { factory = factory == null ? new DummyConcurrentFactory() : factory; return constructorIAi.newInstance(config, factory, remoteAddress, remotePort, localAddress, localPort, parser, ref); } catch (Exception e) { throw new TransportException("Cannot create an instance of " + connectionClass, TransportError.Internal, e); } } @Override public IConnection createConnection(InetAddress remoteAddress, IConcurrentFactory factory, int remotePort, InetAddress localAddress, int localPort, IConnectionListener listener, String ref) throws TransportException { try { factory = factory == null ? new DummyConcurrentFactory() : factory; return constructorIAiCL.newInstance(config, factory, remoteAddress, remotePort, localAddress, localPort, listener, parser, ref); } catch (Exception e) { throw new TransportException("Cannot create an instance of " + connectionClass, TransportError.Internal, e); } } @Override public boolean isWrapperFor(Class aClass) throws InternalException { return false; } @Override public T unwrap(Class aClass) throws InternalException { return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/TCPClientConnection.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.transport.tcp; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.io.IConnection; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.TransportError; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.parser.MessageParser; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class TCPClientConnection implements IConnection { private static Logger logger = LoggerFactory.getLogger(TCPClientConnection.class); private final long createdTime; private TCPTransportClient client; //FIXME : requires JDK6 : protected LinkedBlockingDeque buffer = new LinkedBlockingDeque(64); private LinkedBlockingQueue buffer = new LinkedBlockingQueue(64); private IMessageParser parser; private Lock lock = new ReentrantLock(); private ConcurrentLinkedQueue listeners = new ConcurrentLinkedQueue(); // Cached value for connection key private String cachedKey = null; protected TCPClientConnection(IConcurrentFactory concurrentFactory, IMessageParser parser) { this.createdTime = System.currentTimeMillis(); this.parser = parser; client = new TCPTransportClient(concurrentFactory, this); } public TCPClientConnection(Configuration config, IConcurrentFactory concurrentFactory, Socket socket, IMessageParser parser, String ref) throws Exception { this(concurrentFactory, parser); client = new TCPTransportClient(concurrentFactory, this); client.initialize(socket); client.start(); } public TCPClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IMessageParser parser, String ref) { this(concurrentFactory, parser); client.setDestAddress(new InetSocketAddress(remoteAddress, remotePort)); client.setOrigAddress(new InetSocketAddress(localAddress, localPort)); } public TCPClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IConnectionListener listener, IMessageParser parser, String ref) { this(concurrentFactory, parser); client.setDestAddress(new InetSocketAddress(remoteAddress, remotePort)); client.setOrigAddress(new InetSocketAddress(localAddress, localPort)); listeners.add(listener); } @Override public long getCreatedTime() { return createdTime; } @Override public void connect() throws TransportException { try { getClient().initialize(); getClient().start(); } catch (IOException e) { throw new TransportException("Cannot init transport: ", TransportError.NetWorkError, e); } catch (Exception e) { throw new TransportException("Cannot init transport: ", TransportError.Internal, e); } } @Override public void disconnect() throws InternalError { //PCB added logging logger.debug("In disconnect for [{}]", this.getKey()); try { if (getClient() != null) { getClient().stop(); } } catch (Exception e) { throw new InternalError("Error while stopping transport: " + e.getMessage()); } } @Override public void release() throws IOException { //PCB added logging logger.debug("In release for [{}]", this.getKey()); try { if (getClient() != null) { getClient().release(); } } catch (Exception e) { throw new IOException(e.getMessage()); } finally { parser = null; buffer.clear(); remAllConnectionListener(); } } @Override public void sendMessage(IMessage message) throws TransportException, OverloadException { try { if (getClient() != null) { //PCB added logging //Long receivedAt = timerMap.remove(message.getEndToEndIdentifier() + "_"+ message.getHopByHopIdentifier()); //if (receivedAt != null) { // long millis = System.currentTimeMillis() - receivedAt; // if (millis >= 200) { // logger.warn("Diameter Message processing took [{}]ms", millis); // } //} getClient().sendMessage(parser.encodeMessage(message)); //PCB added logging //if (receivedAt != null) { // long millis = System.currentTimeMillis() - receivedAt; // if (millis >= 200) { // logger.warn("Diameter Message processing and sending took [{}]ms", millis); // } //} } } catch (Exception e) { throw new TransportException("Cannot send message: ", TransportError.FailedSendMessage, e); } } protected TCPTransportClient getClient() { return client; } @Override public boolean isNetworkInitiated() { return false; } @Override public boolean isConnected() { return getClient() != null && getClient().isConnected(); } @Override public InetAddress getRemoteAddress() { return getClient().getDestAddress().getAddress(); } @Override public int getRemotePort() { return getClient().getDestAddress().getPort(); } @Override public void addConnectionListener(IConnectionListener listener) { lock.lock(); try { listeners.add(listener); if (buffer.size() != 0) { for (Event e : buffer) { try { //PCB added logging logger.debug("Processing event from buffer"); onEvent(e); } catch (AvpDataException e1) { // ignore } } buffer.clear(); } } finally { lock.unlock(); } } @Override public void remAllConnectionListener() { //PCB added logging logger.debug("Waiting to get lock in order to remove all listeners"); lock.lock(); try { //PCB added logging logger.debug("Removing all listeners on [{}]", this.getKey()); listeners.clear(); } finally { lock.unlock(); } } @Override public void remConnectionListener(IConnectionListener listener) { lock.lock(); try { //PCB added logging logger.debug("Removing listener [{}] on [{}]", listener.getClass().getName(), this.getKey()); listeners.remove(listener); } finally { lock.unlock(); } } @Override public boolean isWrapperFor(Class aClass) throws InternalException { return false; } @Override public T unwrap(Class aClass) throws InternalException { return null; } @Override public String getKey() { if (this.cachedKey == null) { this.cachedKey = new StringBuffer("aaa://").append(getRemoteAddress().getHostName()).append(":") .append(getRemotePort()).toString(); } return this.cachedKey; } protected void onDisconnect() throws AvpDataException { onEvent(new Event(EventType.DISCONNECTED)); } protected void onMessageReceived(ByteBuffer message) throws AvpDataException { if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { String hex = MessageParser.byteArrayToHexString(message.array()); logger.trace("Received message of size [{}]\n{}", new Object[] { message.array().length, hex }); } else { logger.debug("Received message of size [{}]", message.array().length); } } onEvent(new Event(EventType.MESSAGE_RECEIVED, message)); } protected void onAvpDataException(AvpDataException e) { try { onEvent(new Event(EventType.DATA_EXCEPTION, e)); } catch (AvpDataException e1) { // ignore } } protected void onConnected() { try { onEvent(new Event(EventType.CONNECTED)); } catch (AvpDataException e1) { // ignore } } protected void onEvent(Event event) throws AvpDataException { //PCB added logging logger.debug("In onEvent for connection [{}]. Getting lock", this.getKey()); lock.lock(); //PCB added logging logger.debug("Got lock"); try { if (processBufferedMessages(event)) { for (IConnectionListener listener : listeners) { //PCB added logging if (logger.isDebugEnabled()) { logger.debug("Passing event to listener. Event type is [{}]", event.type.toString()); } switch (event.type) { case CONNECTED: listener.connectionOpened(getKey()); break; case DISCONNECTED: listener.connectionClosed(getKey(), null); break; case MESSAGE_RECEIVED: //PCB added IMessage msg = parser.createMessage(event.message); //timerMap.put(msg.getEndToEndIdentifier() + "_"+ msg.getHopByHopIdentifier(), System.currentTimeMillis()); listener.messageReceived(getKey(), msg); break; case DATA_EXCEPTION: listener.internalError(getKey(), null, new TransportException("Avp Data Exception:", TransportError.ReceivedBrokenMessage, event.exception)); break; } } } } finally { logger.debug("Releasing lock and finished onEvent for connection [{}]", this.getKey()); lock.unlock(); } } //private static final Map timerMap = new ConcurrentHashMap(); protected boolean processBufferedMessages(Event event) throws AvpDataException { if (listeners.size() == 0) { //PCB added logging logger.debug("listeners.size() == 0 on connection [{}]", this.getKey()); try { buffer.add(event); } catch (IllegalStateException e) { logger.debug("Got IllegalStateException in processBufferedMessages"); // FIXME : requires JDK6 : buffer.removeLast(); Event[] tempBuffer = buffer.toArray(new Event[buffer.size()]); buffer.remove(tempBuffer[tempBuffer.length - 1]); buffer.add(event); } //PCB added logging logger.debug("processBufferedMessages is returning false"); return false; } else { logger.debug("processBufferedMessages is returning true on connection [{}] as there are listeners", getKey()); return true; } } //------------------ helper classes ------------------------ private enum EventType { CONNECTED, DISCONNECTED, MESSAGE_RECEIVED, DATA_EXCEPTION } private static class Event { EventType type; ByteBuffer message; Exception exception; Event(EventType type) { this.type = type; } Event(EventType type, Exception exception) { this(type); this.exception = exception; } Event(EventType type, ByteBuffer message) { this(type); this.message = message; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/TCPTransportClient.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.transport.tcp; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.BufferOverflowException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.channels.*; import java.nio.channels.spi.SelectorProvider; import java.util.Iterator; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.AvpDataException; import org.jdiameter.client.api.io.NotInitializedException; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class TCPTransportClient implements Runnable { private TCPClientConnection parentConnection; private IConcurrentFactory concurrentFactory; public static final int DEFAULT_BUFFER_SIZE = 1024; public static final int DEFAULT_STORAGE_SIZE = 2048; protected boolean stop = false; protected Thread selfThread; protected int bufferSize = DEFAULT_BUFFER_SIZE; protected ByteBuffer buffer = ByteBuffer.allocate(this.bufferSize); protected InetSocketAddress destAddress; protected InetSocketAddress origAddress; protected SocketChannel socketChannel; protected Lock lock = new ReentrantLock(); protected int storageSize = DEFAULT_STORAGE_SIZE; protected ByteBuffer storage = ByteBuffer.allocate(storageSize); private String socketDescription = null; private static final Logger logger = LoggerFactory.getLogger(TCPTransportClient.class); //PCB - allow non blocking IO private static final boolean BLOCKING_IO = false; private static final long SELECT_TIMEOUT = 500; // milliseconds public TCPTransportClient() { } /** * Default constructor * * @param concurrentFactory factory for create threads * @param parenConnection connection created this transport */ TCPTransportClient(IConcurrentFactory concurrentFactory, TCPClientConnection parenConnection) { this.parentConnection = parenConnection; this.concurrentFactory = concurrentFactory; } /** * Network init socket */ public void initialize() throws IOException, NotInitializedException { logger.debug("Initialising TCPTransportClient. Origin address is [{}] and destination address is [{}]", origAddress, destAddress); if (destAddress == null) { throw new NotInitializedException("Destination address is not set"); } socketChannel = SelectorProvider.provider().openSocketChannel(); if (origAddress != null) { socketChannel.socket().bind(origAddress); } socketChannel.connect(destAddress); //PCB added logging socketChannel.configureBlocking(BLOCKING_IO); getParent().onConnected(); } public TCPClientConnection getParent() { return parentConnection; } public void initialize(Socket socket) throws IOException, NotInitializedException { logger.debug("Initialising TCPTransportClient for a socket on [{}]", socket); socketDescription = socket.toString(); socketChannel = socket.getChannel(); //PCB added logging socketChannel.configureBlocking(BLOCKING_IO); destAddress = new InetSocketAddress(socket.getInetAddress(), socket.getPort()); } public void start() throws NotInitializedException { // for client if (socketDescription == null && socketChannel != null) { socketDescription = socketChannel.socket().toString(); } logger.debug("Starting transport. Socket is {}", socketDescription); if (socketChannel == null) { throw new NotInitializedException("Transport is not initialized"); } if (!socketChannel.isConnected()) { throw new NotInitializedException("Socket channel is not connected"); } if (getParent() == null) { throw new NotInitializedException("No parent connection is set is set"); } if (selfThread == null || !selfThread.isAlive()) { concurrentFactory.getThreadPool().execute(this); } } //PCB added logging @Override public void run() { // Workaround for Issue #4 (http://code.google.com/p/jdiameter/issues/detail?id=4) // BEGIN WORKAROUND // Give some time to initialization... int sleepTime = 250; logger.debug("Sleeping for {}ms before starting transport so that listeners can all be added and ready for messages", sleepTime); try { Thread.sleep(sleepTime); } catch (InterruptedException e) { // ignore } logger.debug("Finished sleeping for {}ms. By now, MutablePeerTableImpl should have added its listener", sleepTime); logger.debug("Transport is started. Socket is [{}]", socketDescription); Selector selector = null; try { selector = Selector.open(); socketChannel.register(selector, SelectionKey.OP_READ); while (!stop) { selector.select(SELECT_TIMEOUT); Iterator it = selector.selectedKeys().iterator(); while (it.hasNext()) { // Get the selection key SelectionKey selKey = it.next(); // Remove it from the list to indicate that it is being processed it.remove(); if (selKey.isValid() && selKey.isReadable()) { // Get channel with bytes to read SocketChannel sChannel = (SocketChannel) selKey.channel(); int dataLength = sChannel.read(buffer); logger.debug("Just read [{}] bytes on [{}]", dataLength, socketDescription); if (dataLength == -1) { stop = true; break; } buffer.flip(); byte[] data = new byte[buffer.limit()]; buffer.get(data); append(data); buffer.clear(); } } } } catch (ClosedByInterruptException e) { logger.error("Transport exception ", e); } catch (AsynchronousCloseException e) { logger.error("Transport is closed"); } catch (Throwable e) { logger.error("Transport exception ", e); } finally { try { clearBuffer(); if (selector != null) { selector.close(); } if (socketChannel != null && socketChannel.isOpen()) { socketChannel.close(); } getParent().onDisconnect(); } catch (Exception e) { logger.error("Error", e); } stop = false; logger.info("Read thread is stopped for socket [{}]", socketDescription); } } public void stop() throws Exception { logger.debug("Stopping transport. Socket is [{}]", socketDescription); stop = true; if (socketChannel != null && socketChannel.isOpen()) { socketChannel.close(); } if (selfThread != null) { selfThread.join(100); } clearBuffer(); logger.debug("Transport is stopped. Socket is [{}]", socketDescription); } public void release() throws Exception { stop(); destAddress = null; } private void clearBuffer() throws IOException { bufferSize = DEFAULT_BUFFER_SIZE; buffer = ByteBuffer.allocate(bufferSize); } public InetSocketAddress getDestAddress() { return this.destAddress; } public void setDestAddress(InetSocketAddress address) { this.destAddress = address; if (logger.isDebugEnabled()) { logger.debug("Destination address is set to [{}] : [{}]", destAddress.getHostName(), destAddress.getPort()); } } public void setOrigAddress(InetSocketAddress address) { this.origAddress = address; if (logger.isDebugEnabled()) { logger.debug("Origin address is set to [{}] : [{}]", origAddress.getHostName(), origAddress.getPort()); } } public InetSocketAddress getOrigAddress() { return this.origAddress; } public void sendMessage(ByteBuffer bytes) throws IOException { if (logger.isDebugEnabled()) { logger.debug("About to send a byte buffer of size [{}] over the TCP nio socket [{}]", bytes.array().length, socketDescription); } int rc = 0; // PCB - removed locking // ZhixiaoLuo: Fix #28, without the lock the data in the socketChannel will get mixed in multi-threads. lock.lock(); try { while (rc < bytes.array().length) { rc += socketChannel.write(bytes); } } catch (Exception e) { logger.error("Unable to send message", e); throw new IOException("Error while sending message: " + e); } finally { lock.unlock(); } if (rc == -1) { throw new IOException("Connection closed"); } if (logger.isDebugEnabled()) { logger.debug("Sent a byte buffer of size [{}] over the TCP nio socket [{}]", bytes.array().length, socketDescription); } } @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("Transport to "); if (this.destAddress != null) { buffer.append(this.destAddress.getHostName()); buffer.append(":"); buffer.append(this.destAddress.getPort()); } else { buffer.append("null"); } buffer.append("@"); buffer.append(super.toString()); return buffer.toString(); } boolean isConnected() { return socketChannel != null && socketChannel.isOpen() && socketChannel.isConnected(); } /** * Adds data to storage * * @param data data to add */ private void append(byte[] data) { if (storage.position() + data.length >= storage.capacity()) { ByteBuffer tmp = ByteBuffer.allocate(storage.limit() + data.length * 2); byte[] tmpData = new byte[storage.position()]; storage.flip(); storage.get(tmpData); tmp.put(tmpData); storage = tmp; logger.warn("Increase storage size. Current size is {}", storage.array().length); } try { storage.put(data); } catch (BufferOverflowException boe) { logger.error("Buffer overflow occured", boe); } boolean messageReceived; do { messageReceived = seekMessage(); } while (messageReceived); } private boolean seekMessage() { // make sure there's actual data written on the buffer if (storage.position() == 0) { return false; } storage.flip(); try { // get first four bytes for version and message length // 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | Version | Message Length | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ int tmp = storage.getInt(); // reset position so we can now read whole message storage.position(0); // check that version is 1, as per RFC 3588 - Section 3: // This Version field MUST be set to 1 to indicate Diameter Version 1 byte vers = (byte) (tmp >> 24); if (vers != 1) { // ZhixiaoLuo: fix #28, if unlucky storage.limit < data.length(1024), then always failed to do storage.put(data) // ZhixiaoLuo: and get BufferOverflowException in append(data) storage.clear(); return false; } // extract the message length, so we know how much to read int messageLength = (tmp & 0xFFFFFF); // verify that we do have the whole message in the storage if (storage.limit() < messageLength) { // we don't have it all.. let's restore buffer to receive more storage.position(storage.limit()); storage.limit(storage.capacity()); logger.debug("Received partial message, waiting for remaining (expected: {} bytes, got {} bytes).", messageLength, storage.position()); return false; } // read the complete message byte[] data = new byte[messageLength]; storage.get(data); storage.compact(); try { // make a message out of data and process it logger.debug("Passing message on to parent"); getParent().onMessageReceived(ByteBuffer.wrap(data)); logger.debug("Finished passing message on to parent"); } catch (AvpDataException e) { logger.debug("Garbage was received. Discarding."); storage.clear(); getParent().onAvpDataException(e); } } catch (BufferUnderflowException bue) { // we don't have enough data to read message length.. wait for more storage.position(storage.limit()); storage.limit(storage.capacity()); logger.debug("Buffer underflow occured, waiting for more data.", bue); return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/netty/DiameterMessageDecoder.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tcp.netty; import java.util.List; import org.jdiameter.api.AvpDataException; import org.jdiameter.client.api.parser.IMessageParser; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class DiameterMessageDecoder extends ByteToMessageDecoder { protected final IMessageParser parser; protected final TCPClientConnection parentConnection; public DiameterMessageDecoder(TCPClientConnection parentConnection, IMessageParser parser) { this.parser = parser; this.parentConnection = parentConnection; } @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { if (in.readableBytes() >= 4) { int first = in.getInt(in.readerIndex()); byte version = (byte) (first >> 24); if (version != 1) { return; } int messageLength = (first & 0xFFFFFF); if (in.readableBytes() < messageLength) { return; } byte[] bytes = new byte[messageLength]; in.readBytes(bytes); try { out.add(this.parser.createMessage(bytes)); } catch (AvpDataException e) { this.parentConnection.onAvpDataException(e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/netty/DiameterMessageEncoder.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tcp.netty; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class DiameterMessageEncoder extends MessageToByteEncoder { protected final IMessageParser parser; public DiameterMessageEncoder(IMessageParser parser) { this.parser = parser; } @Override protected void encode(ChannelHandlerContext ctx, IMessage msg, ByteBuf out) throws Exception { out.writeBytes(Unpooled.wrappedBuffer(parser.encodeMessage(msg))); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/netty/DiameterMessageHandler.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tcp.netty; import org.jdiameter.api.AvpDataException; import org.jdiameter.client.api.IMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class DiameterMessageHandler extends ChannelInboundHandlerAdapter { protected static final Logger logger = LoggerFactory.getLogger(DiameterMessageHandler.class); protected final TCPClientConnection parentConnection; public DiameterMessageHandler(TCPClientConnection parentConnection) { this.parentConnection = parentConnection; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { logger.debug("Received message TCP Transport from [{}]", ctx.channel().remoteAddress()); IMessage m = (IMessage) msg; try { logger.debug("Passing message on to parent"); parentConnection.onMessageReceived(m); logger.debug("Finished passing message on to parent"); } catch (AvpDataException e) { logger.debug("Garbage was received. Discarding."); parentConnection.onAvpDataException(e); } finally { ReferenceCountUtil.release(m); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.error(cause.getMessage(), cause); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/netty/TCPClientConnection.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tcp.netty; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.io.IConnection; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.TransportError; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.channel.Channel; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class TCPClientConnection implements IConnection { private static Logger logger = LoggerFactory.getLogger(TCPClientConnection.class); private final long createdTime = System.currentTimeMillis(); private TCPTransportClient client; // FIXME : requires JDK6 : protected LinkedBlockingDeque buffer = new // LinkedBlockingDeque(64); private LinkedBlockingQueue buffer = new LinkedBlockingQueue(64); private IMessageParser parser; private Lock lock = new ReentrantLock(); private ConcurrentLinkedQueue listeners = new ConcurrentLinkedQueue(); // Cached value for connection key private String cachedKey = null; public TCPClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IMessageParser parser, String ref) { this.parser = parser; this.client = new TCPTransportClient(this, parser, new InetSocketAddress(remoteAddress, remotePort), new InetSocketAddress(localAddress, localPort)); } public TCPClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IConnectionListener listener, IMessageParser parser, String ref) { this(config, concurrentFactory, remoteAddress, remotePort, localAddress, localPort, parser, ref); listeners.add(listener); } public TCPClientConnection(Channel channel, IMessageParser parser) { this.parser = parser; this.client = new TCPTransportClient(this, parser, channel); } public long getCreatedTime() { return createdTime; } public void connect() throws TransportException { try { this.client.start(); } catch (Exception e) { throw new TransportException("Cannot init transport: ", TransportError.Internal, e); } } public void disconnect() throws InternalError { logger.debug("In disconnect for [{}]", this.getKey()); try { if (this.client != null) { this.client.stop(); } } catch (Exception e) { throw new InternalError("Error while stopping transport: " + e.getMessage()); } } public void release() throws IOException { logger.debug("In release for [{}]", this.getKey()); try { if (this.client != null) { this.client.release(); } } catch (Exception e) { throw new IOException(e.getMessage()); } finally { parser = null; buffer.clear(); remAllConnectionListener(); } } public void sendMessage(IMessage message) throws TransportException, OverloadException { try { if (this.client != null) { this.client.sendMessage(message); } } catch (Exception e) { throw new TransportException("Cannot send message: ", TransportError.FailedSendMessage, e); } } protected TCPTransportClient getClient() { return this.client; } public boolean isNetworkInitiated() { return false; } public boolean isConnected() { return this.client != null && this.client.isConnected(); } public InetAddress getRemoteAddress() { return this.client.getDestAddress().getAddress(); } public int getRemotePort() { return this.client.getDestAddress().getPort(); } public void addConnectionListener(IConnectionListener listener) { lock.lock(); try { listeners.add(listener); if (buffer.size() != 0) { for (Event e : buffer) { try { logger.debug("Processing event from buffer"); onEvent(e); } catch (AvpDataException e1) { // ignore } } buffer.clear(); } } finally { lock.unlock(); } } public void remAllConnectionListener() { logger.debug("Waiting to get lock in order to remove all listeners"); lock.lock(); try { logger.debug("Removing all listeners on [{}]", this.getKey()); listeners.clear(); } finally { lock.unlock(); } } public void remConnectionListener(IConnectionListener listener) { lock.lock(); try { logger.debug("Removing listener [{}] on [{}]", listener.getClass().getName(), this.getKey()); listeners.remove(listener); } finally { lock.unlock(); } } public boolean isWrapperFor(Class aClass) throws InternalException { return false; } public T unwrap(Class aClass) throws InternalException { return null; } public String getKey() { if (this.cachedKey == null) { this.cachedKey = new StringBuffer("aaa://").append(getRemoteAddress().getHostName()).append(":") .append(getRemotePort()) .toString(); } return this.cachedKey; } protected void onDisconnect() throws AvpDataException { onEvent(new Event(EventType.DISCONNECTED)); } protected void onMessageReceived(IMessage message) throws AvpDataException { onEvent(new Event(EventType.MESSAGE_RECEIVED, message)); } protected void onAvpDataException(AvpDataException e) { try { onEvent(new Event(EventType.DATA_EXCEPTION, e)); } catch (AvpDataException e1) { // ignore } } protected void onConnected() { try { onEvent(new Event(EventType.CONNECTED)); } catch (AvpDataException e1) { // ignore } } protected void onEvent(Event event) throws AvpDataException { logger.debug("In onEvent for connection [{}]. Getting lock", this.getKey()); lock.lock(); logger.debug("Got lock"); try { if (processBufferedMessages(event)) { for (IConnectionListener listener : listeners) { if (logger.isDebugEnabled()) { logger.debug("Passing event to listener. Event type is [{}]", event.type.toString()); } switch (event.type) { case CONNECTED: listener.connectionOpened(getKey()); break; case DISCONNECTED: listener.connectionClosed(getKey(), null); break; case MESSAGE_RECEIVED: listener.messageReceived(getKey(), event.message); break; case DATA_EXCEPTION: listener.internalError(getKey(), null, new TransportException("Avp Data Exception:", TransportError.ReceivedBrokenMessage, event.exception)); break; } } } } finally { logger.debug("Releasing lock and finished onEvent for connection [{}]", this.getKey()); lock.unlock(); } } protected boolean processBufferedMessages(Event event) throws AvpDataException { if (listeners.size() == 0) { logger.debug("listeners.size() == 0 on connection [{}]", this.getKey()); try { buffer.add(event); } catch (IllegalStateException e) { logger.debug("Got IllegalStateException in processBufferedMessages"); // FIXME : requires JDK6 : buffer.removeLast(); Event[] tempBuffer = buffer.toArray(new Event[buffer.size()]); buffer.remove(tempBuffer[tempBuffer.length - 1]); buffer.add(event); } logger.debug("processBufferedMessages is returning false"); return false; } else { logger.debug("processBufferedMessages is returning true on connection [{}] as there are listeners", getKey()); return true; } } // ------------------ helper classes ------------------------ private enum EventType { CONNECTED, DISCONNECTED, MESSAGE_RECEIVED, DATA_EXCEPTION } private static class Event { EventType type; IMessage message; Exception exception; Event(EventType type) { this.type = type; } Event(EventType type, Exception exception) { this(type); this.exception = exception; } Event(EventType type, IMessage message) { this(type); this.message = message; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tcp/netty/TCPTransportClient.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tcp.netty; import java.io.IOException; import java.net.InetSocketAddress; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.util.concurrent.DefaultEventExecutorGroup; import io.netty.util.concurrent.EventExecutorGroup; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class TCPTransportClient { protected EventLoopGroup workerGroup; protected EventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(1); protected Channel channel; protected TCPClientConnection parentConnection; protected InetSocketAddress destAddress; protected InetSocketAddress sourceAddress; // TODO: what? protected String socketDescription; protected static final Logger logger = LoggerFactory.getLogger(TCPClientConnection.class); protected IMessageParser parser; protected static final int CONNECT_TIMEOUT = 500; // mills protected TCPTransportClient(TCPClientConnection parentConnection, IMessageParser parser) { if (parentConnection == null) { throw new IllegalArgumentException("Parent connection cannot be null"); } this.parentConnection = parentConnection; if (parser == null) { throw new IllegalArgumentException("Parser cannot be null"); } this.parser = parser; } public TCPTransportClient(TCPClientConnection parentConnection, IMessageParser parser, InetSocketAddress destAddress, InetSocketAddress sourceAddress) { this(parentConnection, parser); logger.debug("Client only connection"); if (destAddress == null && sourceAddress == null) { throw new IllegalArgumentException("Either Destination or Source address is required"); } if (sourceAddress != null) { this.sourceAddress = sourceAddress; } if (destAddress != null) { this.destAddress = destAddress; this.socketDescription = destAddress.toString(); } } public TCPTransportClient(TCPClientConnection parentConnection, IMessageParser parser, Channel channel) { this(parentConnection, parser); logger.debug("Server only connection"); if (channel == null) { throw new IllegalArgumentException("Channel cannot be null"); } this.channel = channel; ChannelPipeline pipeline = this.channel.pipeline(); pipeline.addLast("decoder", new DiameterMessageDecoder(parentConnection, parser)); pipeline.addLast("encoder", new DiameterMessageEncoder(parser)); pipeline.addLast(eventExecutorGroup, "msgHandler", new DiameterMessageHandler(parentConnection)); this.destAddress = (InetSocketAddress) this.channel.remoteAddress(); } public void start() throws InterruptedException { logger.debug("Starting TCP Transport on [{}]", socketDescription); if (isConnected()) { logger.debug("TCP Transport already started, [{}]", socketDescription); return; } this.workerGroup = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap().group(workerGroup).channel(NioSocketChannel.class) .option(ChannelOption.SO_KEEPALIVE, true).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT) .handler(new ChannelInitializer() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("decoder", new DiameterMessageDecoder(parentConnection, parser)); pipeline.addLast("encoder", new DiameterMessageEncoder(parser)); pipeline.addLast(eventExecutorGroup, "msgHandler", new DiameterMessageHandler(parentConnection)); } }); this.channel = bootstrap.remoteAddress(destAddress).connect().sync().channel(); logger.debug("TCP Transport connected successfully, [{}]", socketDescription); parentConnection.onConnected(); } public void stop() { logger.debug("Stopping TCP Transport, [{}]", socketDescription); if (!isConnected()) { logger.debug("Already stoppped TCP Transport, [{}]", socketDescription); return; } closeChannel(); closeWorkerGroup(); closeEventExecutorGroup(); logger.debug("Transport is stopped [{}]", socketDescription); } private void closeEventExecutorGroup() { if (eventExecutorGroup != null) { try { eventExecutorGroup.shutdownGracefully().sync(); } catch (InterruptedException e) { logger.error("Error stopping socket " + socketDescription, e); } eventExecutorGroup = null; } } private void closeWorkerGroup() { if (workerGroup != null) { try { workerGroup.shutdownGracefully().sync(); } catch (InterruptedException e) { logger.error("Error stopping socket " + socketDescription, e); } workerGroup = null; } } private void closeChannel() { if (channel != null) { try { channel.closeFuture().sync(); } catch (InterruptedException e) { logger.error("Error stopping socket " + socketDescription, e); } channel = null; } } public void release() throws InterruptedException, IOException { logger.debug("Releasing TCP Transport, [{}]", socketDescription); stop(); destAddress = null; sourceAddress = null; } public void sendMessage(IMessage message) { if (!isConnected()) { throw new IllegalStateException("TCP transport is stopped on socket " + socketDescription); } channel.writeAndFlush(message); } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("Transport to "); if (this.destAddress != null) { buffer.append(this.destAddress.getHostName()); buffer.append(":"); buffer.append(this.destAddress.getPort()); } else { buffer.append("null"); } buffer.append("@"); buffer.append(super.toString()); return buffer.toString(); } public TCPClientConnection getParent() { return parentConnection; } public InetSocketAddress getDestAddress() { return this.destAddress; } boolean isConnected() { return channel != null && channel.isActive(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/TLSClientConnection.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.transport.tls; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.io.IConnection; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.TransportError; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class TLSClientConnection implements IConnection { private static Logger logger = LoggerFactory.getLogger(TLSClientConnection.class); private TLSTransportClient client; private SSLSocketFactory factory; private Configuration sslConfig; private final long createdTime; private LinkedBlockingQueue buffer = new LinkedBlockingQueue(64); private Lock lock = new ReentrantLock(); private ConcurrentLinkedQueue listeners = new ConcurrentLinkedQueue(); // Cached value for connection key private String cachedKey = null; public TLSClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IMessageParser parser, String ref) { this.createdTime = System.currentTimeMillis(); this.client = new TLSTransportClient(this, concurrentFactory, parser); this.client.setDestAddress(new InetSocketAddress(remoteAddress, remotePort)); this.client.setOrigAddress(new InetSocketAddress(localAddress, localPort)); try { if (ref == null) { throw new Exception("Can not create connection without TLS parameters"); } logger.trace("Initializing TLS with reference '{}'", ref); this.factory = fillSecurityData(config, ref); } catch (Exception e) { throw new IllegalArgumentException(e); } } public TLSClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IConnectionListener listener, IMessageParser parser, String ref) { this.createdTime = System.currentTimeMillis(); this.listeners.add(listener); this.client = new TLSTransportClient(this, concurrentFactory, parser); this.client.setDestAddress(new InetSocketAddress(remoteAddress, remotePort)); this.client.setOrigAddress(new InetSocketAddress(localAddress, localPort)); try { if (ref == null) { throw new Exception("Can not create connection without TLS parameters"); } logger.trace("Initializing TLS with reference '{}'", ref); this.factory = fillSecurityData(config, ref); } catch (Exception e) { throw new IllegalArgumentException(e); } } public TLSClientConnection(Configuration config, Configuration localPeerSSLConfig, IConcurrentFactory concurrentFactory, Socket socket, IMessageParser parser) throws Exception { this.createdTime = System.currentTimeMillis(); this.sslConfig = localPeerSSLConfig; this.client = new TLSTransportClient(this, concurrentFactory, parser); this.client.setDestAddress(new InetSocketAddress(socket.getRemoteSocketAddress().toString(), socket.getPort())); this.client.setOrigAddress(new InetSocketAddress(socket.getInetAddress().getHostAddress(), socket.getLocalPort())); this.client.initialize(socket); this.client.start(); try { if (localPeerSSLConfig == null) { throw new Exception("Can not create connection without TLS parameters"); } this.factory = fillSecurityData(localPeerSSLConfig); } catch (Exception e) { throw new IllegalArgumentException(e); } } protected SSLSocketFactory fillSecurityData(Configuration config, String ref) throws Exception { sslConfig = TLSUtils.getSSLConfiguration(config, ref); if (sslConfig == null) { throw new Exception("Incorrect reference to secutity data"); } return getSSLContext(sslConfig); } protected SSLSocketFactory fillSecurityData(Configuration config) throws Exception { return getSSLContext(config); } protected TLSTransportClient getClient() { return client; } public Configuration getSSLConfig() { return sslConfig; } public SSLSocketFactory getSSLFactory() { return factory; } private SSLSocketFactory getSSLContext(Configuration sslConfig) throws Exception { SSLContext ctx = TLSUtils.getSecureContext(sslConfig); return ctx.getSocketFactory(); } @Override public long getCreatedTime() { return createdTime; } @Override public InetAddress getRemoteAddress() { return getClient().getDestAddress().getAddress(); } @Override public int getRemotePort() { return getClient().getDestAddress().getPort(); } @Override public void addConnectionListener(IConnectionListener listener) { lock.lock(); try { listeners.add(listener); if (buffer.size() != 0) { for (Event e : buffer) { try { onEvent(e); } catch (AvpDataException e1) { // ignore } } buffer.clear(); } } finally { lock.unlock(); } } @Override public void remAllConnectionListener() { lock.lock(); try { listeners.clear(); } finally { lock.unlock(); } } @Override public void remConnectionListener(IConnectionListener listener) { lock.lock(); try { listeners.remove(listener); } finally { lock.unlock(); } } @Override public void release() throws IOException { try { if (getClient() != null) { getClient().release(); } } catch (Exception e) { throw new IOException(e.getMessage()); } finally { buffer.clear(); remAllConnectionListener(); } } @Override public boolean isWrapperFor(Class aClass) throws InternalException { return false; } @Override public T unwrap(Class aClass) throws InternalException { return null; } @Override public boolean isConnected() { return getClient() != null && getClient().isConnected(); } @Override public boolean isNetworkInitiated() { return false; } @Override public String getKey() { if (this.cachedKey == null) { this.cachedKey = new StringBuffer("aaas://").append(getRemoteAddress().getHostName()).append(":") .append(getRemotePort()).toString(); } return this.cachedKey; } @Override public void connect() throws TransportException { try { getClient().initialize(); getClient().start(); } catch (IOException e) { throw new TransportException("Cannot init transport: ", TransportError.NetWorkError, e); } catch (Exception e) { throw new TransportException("Cannot init transport: ", TransportError.Internal, e); } } @Override public void disconnect() throws InternalError { try { if (getClient() != null) { getClient().stop(); } } catch (Exception e) { throw new InternalError("Error while stopping transport: " + e.getMessage()); } } @Override public void sendMessage(IMessage message) throws TransportException, OverloadException { try { if (getClient() != null) { getClient().sendMessage(message); } } catch (Exception e) { throw new TransportException("Cannot send message: ", TransportError.FailedSendMessage, e); } } protected void onDisconnect() throws AvpDataException { onEvent(new Event(EventType.DISCONNECTED)); } protected void onMessageReceived(IMessage message) throws AvpDataException { // if (logger.isDebugEnabled()) { // logger.debug("Received message of size [{}]", message.array().length); // } onEvent(new Event(EventType.MESSAGE_RECEIVED, message)); } protected void onAvpDataException(AvpDataException e) { try { onEvent(new Event(EventType.DATA_EXCEPTION, e)); } catch (AvpDataException e1) { // ignore } } protected void onConnected() { try { onEvent(new Event(EventType.CONNECTED)); } catch (AvpDataException e1) { // ignore } } protected void onEvent(Event event) throws AvpDataException { lock.lock(); try { if (processBufferedMessages(event)) { for (IConnectionListener listener : listeners) { switch (event.type) { case CONNECTED: listener.connectionOpened(getKey()); break; case DISCONNECTED: listener.connectionClosed(getKey(), null); break; case MESSAGE_RECEIVED: listener.messageReceived(getKey(), event.message); break; case DATA_EXCEPTION: listener.internalError(getKey(), null, new TransportException("Avp Data Exception:", TransportError.ReceivedBrokenMessage, event.exception)); break; } } } } finally { lock.unlock(); } } protected boolean processBufferedMessages(Event event) throws AvpDataException { if (listeners.size() == 0) { try { buffer.add(event); } catch (IllegalStateException e) { // FIXME : requires JDK6 : buffer.removeLast(); Event[] tempBuffer = buffer.toArray(new Event[buffer.size()]); buffer.remove(tempBuffer[tempBuffer.length - 1]); buffer.add(event); } return false; } else { return true; } } // --------------------- helper classes ---------------------- private enum EventType { CONNECTED, DISCONNECTED, MESSAGE_RECEIVED, DATA_EXCEPTION } private static class Event { EventType type; IMessage message; Exception exception; Event(EventType type) { this.type = type; } Event(EventType type, Exception exception) { this(type); this.exception = exception; } Event(EventType type, IMessage message) { this(type); this.message = message; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/TLSTransportClient.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.transport.tls; import static org.jdiameter.client.impl.helpers.Parameters.CipherSuites; import static org.jdiameter.client.impl.helpers.Parameters.SDEnableSessionCreation; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.BufferOverflowException; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousCloseException; import java.nio.channels.ClosedByInterruptException; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import javax.net.ssl.HandshakeCompletedEvent; import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Message; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.io.NotInitializedException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class TLSTransportClient { // NOTE: SSL Does not provide channels, need to do plain old sync R/W :/ // So SSLSocket.getChannel() returns NULL! private static final Logger logger = LoggerFactory.getLogger(TLSTransportClient.class); private TLSClientConnection parentConnection; private IConcurrentFactory concurrentFactory; private boolean stop = false; // flag to indicate that initial shake did happen private boolean shaken; // flag indicating that SSL handshake is going on, while this is set to true, no messages can be exchanged. private boolean shaking; private Thread readThread; private InetSocketAddress destAddress; private InetSocketAddress origAddress; private String socketDescription = null; // sync streams to get data. private InputStream inputStream; private OutputStream outputStream; //private SSLSocket sslSocket; private Socket plainSocket; public static final int DEFAULT_BUFFER_SIZE = 4096; public static final int DEFAULT_STORAGE_SIZE = 4096; private int bufferSize = DEFAULT_BUFFER_SIZE; private ByteBuffer buffer = ByteBuffer.allocate(this.bufferSize); private int storageSize = DEFAULT_STORAGE_SIZE; private ByteBuffer storage = ByteBuffer.allocate(storageSize); private Lock lock = new ReentrantLock(); private IMessageParser parser; private final DiameterSSLHandshakeListener handshakeListener = new DiameterSSLHandshakeListener(); private final ReadTask readTash = new ReadTask(); //tell weather we are in a client mode private boolean client; private boolean receivedInband; /** * Default constructor * * @param parenConnection connection created this transport */ public TLSTransportClient(TLSClientConnection parenConnection, IConcurrentFactory concurrentFactory, IMessageParser parser) { this.parentConnection = parenConnection; this.concurrentFactory = concurrentFactory; this.parser = parser; } public void initialize() throws IOException, NotInitializedException { if (destAddress == null) { throw new NotInitializedException("Destination address is not set"); } this.client = true; // SSLSocketFactory cltFct = parentConnection.getSSLFactory(); // this.sslSocket = (SSLSocket) cltFct.createSocket(); // // this.sslSocket.setEnableSessionCreation(parentConnection.getSSLConfig().getBooleanValue(SDEnableSessionCreation.ordinal(), true)); // this.sslSocket.setUseClientMode(true); // if (parentConnection.getSSLConfig().getStringValue(CipherSuites.ordinal(), null) != null) { // this.sslSocket.setEnabledCipherSuites(parentConnection.getSSLConfig().getStringValue(CipherSuites.ordinal(), null).split(",")); // } // // if (this.origAddress != null) { // this.sslSocket.bind(this.origAddress); // } // this.sslSocket.connect(this.destAddress); // // // now lets get streams. // this.sslInputStream = this.sslSocket.getInputStream(); // this.sslOutputStream = this.sslSocket.getOutputStream(); this.plainSocket = new Socket(); if (this.origAddress != null) { this.plainSocket.bind(this.origAddress); } this.plainSocket.connect(this.destAddress); this.inputStream = this.plainSocket.getInputStream(); this.outputStream = this.plainSocket.getOutputStream(); // now, we need to notify parent, this will START CER/CEA exchange // on CEA 2xxx we can enable TLS parentConnection.onConnected(); } public void initialize(Socket socket) throws IOException, NotInitializedException { logger.debug("Initialising TLSTransportClient for a socket on [{}]", socket); this.client = false; this.plainSocket = socket; this.socketDescription = socket.toString(); this.destAddress = new InetSocketAddress(socket.getInetAddress(), socket.getPort()); this.inputStream = this.plainSocket.getInputStream(); this.outputStream = this.plainSocket.getOutputStream(); } public void start() throws NotInitializedException { // for client if (this.socketDescription == null) { this.socketDescription = this.plainSocket.toString(); } logger.debug("Starting transport. Socket is {}", socketDescription); if (!this.plainSocket.isConnected()) { throw new NotInitializedException("Socket is not connected"); } if (getParent() == null) { throw new NotInitializedException("No parent connection is set is set"); } if (this.readThread == null || !this.readThread.isAlive()) { this.concurrentFactory.getThreadPool().execute(this.readTash); } } // ---------------- getters & setters --------------------- public TLSClientConnection getParent() { return parentConnection; } public InetSocketAddress getDestAddress() { return this.destAddress; } public void setDestAddress(InetSocketAddress address) { this.destAddress = address; if (logger.isDebugEnabled()) { logger.debug("Destination address is set to [{}] : [{}]", destAddress.getHostName(), destAddress.getPort()); } } public void setOrigAddress(InetSocketAddress address) { this.origAddress = address; if (logger.isDebugEnabled()) { logger.debug("Origin address is set to [{}] : [{}]", origAddress.getHostName(), origAddress.getPort()); } } public InetSocketAddress getOrigAddress() { return this.origAddress; } // ---------------- helper methods --------------------- void sendMessage(IMessage message) throws IOException, AvpDataException, NotInitializedException, ParseException { if (!isConnected()) { throw new IOException("Failed to send message over [" + socketDescription + "]"); } //switch to wait for SSL handshake to workout. if (!isExchangeAllowed()) { //TODO: do more? return; } doTLSPreSendProcessing(message); final ByteBuffer messageBuffer = this.parser.encodeMessage(message); if (logger.isDebugEnabled()) { logger.debug("About to send a byte buffer of size [{}] over the TLS socket [{}]", messageBuffer.array().length, socketDescription); } lock.lock(); try { this.outputStream.write(messageBuffer.array(), messageBuffer.position(), messageBuffer.limit()); doTLSPostSendProcessing(message); } catch (Exception e) { logger.debug("Unable to send message", e); throw new IOException("Error while sending message: " + e); } finally { lock.unlock(); } if (logger.isDebugEnabled()) { logger.debug("Sent a byte buffer of size [{}] over the TLS nio socket [{}]", messageBuffer.array().length, socketDescription); } } boolean isConnected() { return this.plainSocket != null && this.plainSocket.isConnected(); } void stop() throws Exception { logger.debug("Stopping transport. Socket is [{}]", socketDescription); stop = true; if (plainSocket != null && !plainSocket.isClosed()) { plainSocket.close(); } if (this.readThread != null) { this.readThread.join(100); } clearBuffer(); logger.debug("Transport is stopped. Socket is [{}]", socketDescription); } public void release() throws Exception { stop(); destAddress = null; } void append(byte[] data) { if (storage.position() + data.length >= storage.capacity()) { ByteBuffer tmp = ByteBuffer.allocate(storage.limit() + data.length * 2); byte[] tmpData = new byte[storage.position()]; storage.flip(); storage.get(tmpData); tmp.put(tmpData); storage = tmp; logger.warn("Increase storage size. Current size is {}", storage.array().length); } try { storage.put(data); } catch (BufferOverflowException boe) { logger.error("Buffer overflow occured", boe); } boolean messageReseived; do { messageReseived = seekMessage(storage); } while (messageReseived); } private boolean isExchangeAllowed() { this.lock.lock(); try { return !this.shaking; } finally { this.lock.unlock(); } } private boolean isSuccess(IMessage message) throws AvpDataException { Avp resultAvp = message.getResultCode(); if (resultAvp == null) { resultAvp = message.getAvps().getAvp(Avp.EXPERIMENTAL_RESULT); if (resultAvp == null) { // bad message, ignore if (logger.isDebugEnabled()) { logger.debug( "Discarding message since SSL handshake has not been performed on [{}], dropped message [{}]. No result type avp.", socketDescription, message); } // TODO: anything else? return false; } resultAvp = resultAvp.getGrouped().getAvp(Avp.EXPERIMENTAL_RESULT_CODE); if (resultAvp == null) { // bad message, ignore if (logger.isDebugEnabled()) { logger.debug( "Discarding message since SSL handshake has not been performed on [{}], dropped message [{}]. No result avp.", socketDescription, message); } } } long resultCode = resultAvp.getUnsigned32(); return resultCode >= 2000 && resultCode < 3000; } private boolean seekMessage(ByteBuffer localStorage) { if (storage.position() == 0) { return false; } storage.flip(); int tmp = localStorage.getInt(); localStorage.position(0); byte vers = (byte) (tmp >> 24); if (vers != 1) { return false; } int dataLength = (tmp & 0xFFFFFF); if (localStorage.limit() < dataLength) { localStorage.position(localStorage.limit()); localStorage.limit(localStorage.capacity()); return false; } byte[] data = new byte[dataLength]; localStorage.get(data); localStorage.position(dataLength); localStorage.compact(); ByteBuffer messageBuffer = ByteBuffer.wrap(data); try { if (logger.isDebugEnabled()) { logger.debug("Received message of size [{}]", data.length); } IMessage message = this.parser.createMessage(messageBuffer); // check if if (isExchangeAllowed()) { doTLSPreReceiveProcessing(message); getParent().onMessageReceived(message); } } catch (Exception e) { logger.debug("Garbage was received. Discarding."); storage.clear(); // not a best way. getParent().onAvpDataException(new AvpDataException(e)); } return true; } /** * @param message * @throws AvpDataException * @throws NotInitializedException */ private void doTLSPreReceiveProcessing(IMessage message) throws AvpDataException, NotInitializedException { if (this.shaken) { return; } if (this.client) { // if (CEA && message.isSuccess && message.has(inband)) { // startTLS(); // } if (message.isRequest()) { return; } if (message.getCommandCode() == Message.CAPABILITIES_EXCHANGE_ANSWER && isSuccess(message)) { AvpSet set = message.getAvps(); Avp inbandAvp = set.getAvp(Avp.INBAND_SECURITY_ID); if (inbandAvp != null && inbandAvp.getUnsigned32() == 1) { startTLS(); } } } else { // if (CER && message.has(inband)) { // this.receveidInband = true; // } if (!message.isRequest()) { return; } AvpSet set = message.getAvps(); Avp inbandAvp = set.getAvp(Avp.INBAND_SECURITY_ID); if (inbandAvp != null && inbandAvp.getUnsigned32() == 1) { this.receivedInband = true; } } } /** * @param message */ private void doTLSPreSendProcessing(IMessage message) { if (message.getCommandCode() == Message.CAPABILITIES_EXCHANGE_REQUEST) { AvpSet set = message.getAvps(); set.removeAvp(Avp.INBAND_SECURITY_ID); set.addAvp(Avp.INBAND_SECURITY_ID, 1); } } /** * @param message * @throws AvpDataException * @throws NotInitializedException */ private void doTLSPostSendProcessing(IMessage message) throws AvpDataException, NotInitializedException { // if ( !client && !shaken && CEA && message.isSuccess() && receivedInband) { // startTLS; // } if (this.shaken || this.client || this.plainSocket instanceof SSLSocket || message.isRequest() || message.getCommandCode() != Message.CAPABILITIES_EXCHANGE_ANSWER) { return; } if (this.receivedInband && isSuccess(message)) { this.receivedInband = false; startTLS(); } } /** * @throws NotInitializedException */ private void startTLS() throws NotInitializedException { try { this.shaking = true; SSLSocketFactory cltFct = parentConnection.getSSLFactory(); SSLSocket sslSocket = (SSLSocket) cltFct.createSocket(this.plainSocket, null, this.plainSocket.getPort(), false); sslSocket.setEnableSessionCreation(parentConnection.getSSLConfig().getBooleanValue( SDEnableSessionCreation.ordinal(), true)); // only clients start shake if (parentConnection.getSSLConfig().getStringValue(CipherSuites.ordinal(), null) != null) { sslSocket.setEnabledCipherSuites(parentConnection.getSSLConfig().getStringValue(CipherSuites.ordinal(), null) .split(",")); } this.inputStream = sslSocket.getInputStream(); this.outputStream = sslSocket.getOutputStream(); this.plainSocket = sslSocket; if (this.client) { sslSocket.setUseClientMode(true); // TODO: catch this to check for failure sslSocket.addHandshakeCompletedListener(this.handshakeListener); sslSocket.startHandshake(); } else { sslSocket.addHandshakeCompletedListener(this.handshakeListener); sslSocket.setUseClientMode(false); } } catch (Exception e) { // TODO: ensure close? throw new NotInitializedException(e); } } private void clearBuffer() throws IOException { bufferSize = DEFAULT_BUFFER_SIZE; buffer = ByteBuffer.allocate(bufferSize); } // ---------------- helper classes --------------------- private class DiameterSSLHandshakeListener implements HandshakeCompletedListener { @Override public void handshakeCompleted(HandshakeCompletedEvent event) { // connected comes from here! try { lock.lock(); shaking = false; shaken = true; ((SSLSocket) plainSocket).removeHandshakeCompletedListener(this); getParent().onConnected(); } finally { lock.unlock(); } } } private class ReadTask implements Runnable { @Override public void run() { logger.debug("Transport is started. Socket is [{}]", socketDescription); try { while (!stop) { int dataLength = inputStream.read(buffer.array()); logger.debug("Just read [{}] bytes on [{}]", dataLength, socketDescription); if (dataLength == -1) { break; } buffer.position(dataLength); buffer.flip(); byte[] data = new byte[buffer.limit()]; buffer.get(data); append(data); buffer.clear(); } } catch (ClosedByInterruptException e) { logger.debug("Transport exception ", e); } catch (AsynchronousCloseException e) { logger.debug("Transport exception ", e); } catch (Throwable e) { logger.debug("Transport exception ", e); } finally { try { clearBuffer(); if (plainSocket != null && !plainSocket.isClosed()) { plainSocket.close(); } getParent().onDisconnect(); } catch (Exception e) { logger.debug("Error", e); } stop = false; logger.info("Read thread is stopped for socket [{}]", socketDescription); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/TLSUtils.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.client.impl.transport.tls; import static org.jdiameter.client.impl.helpers.Parameters.*; import java.io.FileInputStream; import java.security.KeyStore; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import org.jdiameter.api.Configuration; /** * Simple utils class just to have one place for common stuff. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class TLSUtils { public static SSLContext getSecureContext(Configuration sslConfig) throws Exception { // TODO: use classloader to fetch files. final String contextTransportAlgo = sslConfig.getStringValue(SDProtocol.ordinal(), null); final Configuration kdConfig = sslConfig.getChildren(KeyData.ordinal())[0]; final Configuration tdConfig = sslConfig.getChildren(TrustData.ordinal())[0]; final String keyManagerAlgo = kdConfig.getStringValue(KDManager.ordinal(), null); final String keyStoreType = kdConfig.getStringValue(KDStore.ordinal(), null); final String keyStorePassword = kdConfig.getStringValue(KDPwd.ordinal(), null); final String keyStoreFile = kdConfig.getStringValue(KDFile.ordinal(), null); final String trustManagerAlgo = tdConfig.getStringValue(TDManager.ordinal(), null); final String trustStoreType = tdConfig.getStringValue(TDStore.ordinal(), null); final String trustStorePassword = tdConfig.getStringValue(TDPwd.ordinal(), null); final String trustStoreFile = tdConfig.getStringValue(TDFile.ordinal(), null); return TLSUtils.getSecureContext(contextTransportAlgo, keyManagerAlgo, keyStoreType, keyStorePassword, keyStoreFile, trustManagerAlgo, trustStoreType, trustStorePassword, trustStoreFile); } public static SSLContext getSecureContext(String contextTransportAlgo, String keyManagerAlgo, String keyStoreType, String keyStorePassword, String keyStoreFile, String trustManagerAlgo, String trustStoreType, String trustStorePassword, String trustStoreFile) throws Exception { System.err.println(KeyManagerFactory.getDefaultAlgorithm()); System.err.println(TrustManagerFactory.getDefaultAlgorithm()); SSLContext ctx = SSLContext.getInstance(contextTransportAlgo); // http://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgo); KeyStore keyStore = KeyStore.getInstance(keyStoreType); char[] key = keyStorePassword.toCharArray(); keyStore.load(new FileInputStream(keyStoreFile), key); keyManagerFactory.init(keyStore, key); KeyManager[] keyManagers = keyManagerFactory.getKeyManagers(); // TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(trustManagerAlgo); KeyStore trustKeyStore = KeyStore.getInstance(trustStoreType); char[] trustKey = trustStorePassword.toCharArray(); trustKeyStore.load(new FileInputStream(trustStoreFile), trustKey); trustManagerFactory.init(trustKeyStore); TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); // ctx.init(keyManagers, trustManagers, null); return ctx; } public static Configuration getSSLConfiguration(Configuration cnf, String ref) { Configuration[] sec = cnf.getChildren(Security.ordinal());// [0].getChildren(SecurityData.ordinal()); for (Configuration i : sec) { if (i.getStringValue(SDName.ordinal(), "").equals(ref)) { return i; } } return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/DiameterMessageDecoder.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import java.util.List; import org.jdiameter.api.AvpDataException; import org.jdiameter.client.api.parser.IMessageParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class DiameterMessageDecoder extends ByteToMessageDecoder { private static final Logger logger = LoggerFactory.getLogger(DiameterMessageDecoder.class); protected final IMessageParser parser; protected final TLSClientConnection parentConnection; public DiameterMessageDecoder(TLSClientConnection parentConnection, IMessageParser parser) { this.parser = parser; this.parentConnection = parentConnection; } @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { logger.debug("Decode message size: {}", in.readableBytes()); if (in.readableBytes() >= 4) { int first = in.getInt(in.readerIndex()); byte version = (byte) (first >> 24); if (version != 1) { return; } int messageLength = (first & 0xFFFFFF); if (in.readableBytes() < messageLength) { return; } logger.debug("Decoding message version: {}, length: {}", version, messageLength); byte[] bytes = new byte[messageLength]; in.readBytes(bytes); try { out.add(this.parser.createMessage(bytes)); } catch (AvpDataException e) { logger.error(e.getMessage(), e); this.parentConnection.onAvpDataException(e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/DiameterMessageEncoder.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class DiameterMessageEncoder extends MessageToByteEncoder { private static final Logger logger = LoggerFactory.getLogger(DiameterMessageEncoder.class); protected final IMessageParser parser; public DiameterMessageEncoder(IMessageParser parser) { this.parser = parser; } @Override protected void encode(ChannelHandlerContext ctx, IMessage msg, ByteBuf out) throws Exception { logger.debug("DiameterMessageEncoder"); logger.debug("Encoding message command code {}", msg.getCommandCode()); out.writeBytes(Unpooled.wrappedBuffer(parser.encodeMessage(msg))); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/DiameterMessageHandler.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import org.jdiameter.api.AvpDataException; import org.jdiameter.client.api.IMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class DiameterMessageHandler extends ChannelInboundHandlerAdapter { protected static final Logger logger = LoggerFactory.getLogger(DiameterMessageHandler.class); protected final TLSClientConnection parentConnection; protected boolean autoRelease; public DiameterMessageHandler(TLSClientConnection parentConnection, boolean autoRelease) { this.parentConnection = parentConnection; this.autoRelease = autoRelease; } public void setAutoRelease(boolean autoRelease) { this.autoRelease = autoRelease; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof IMessage) { IMessage m = (IMessage) msg; logger.debug("Received message {} TLS Transport {}", m.getCommandCode(), this.parentConnection.getKey()); try { logger.debug("Passing message on to parent {}", this.parentConnection.getKey()); parentConnection.onMessageReceived(m); logger.debug("Finished passing message on to parent {}", this.parentConnection.getKey()); } catch (AvpDataException e) { logger.debug("Garbage was received. Discarding. {}", this.parentConnection.getKey()); parentConnection.onAvpDataException(e); } finally { if (autoRelease) { ReferenceCountUtil.release(msg); } else { ctx.fireChannelRead(m); } } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/InbandSecurityHandler.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpSet; import org.jdiameter.client.api.IMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class InbandSecurityHandler extends ChannelOutboundHandlerAdapter { protected static final Logger logger = LoggerFactory.getLogger(InbandSecurityHandler.class); @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { logger.debug("InbandSecurityHandler"); IMessage message = (IMessage) msg; if (message.getCommandCode() == IMessage.CAPABILITIES_EXCHANGE_REQUEST || message.getCommandCode() == IMessage.CAPABILITIES_EXCHANGE_ANSWER) { logger.debug("Writing inband security for CER/CEA msg {}", message.getCommandCode()); AvpSet set = message.getAvps(); set.removeAvp(Avp.INBAND_SECURITY_ID); set.addAvp(Avp.INBAND_SECURITY_ID, 1); } ctx.write(msg, promise); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/SslContextFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import static org.jdiameter.client.impl.helpers.Parameters.*; import java.io.FileInputStream; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLException; import javax.net.ssl.TrustManagerFactory; import org.jdiameter.api.Configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public abstract class SslContextFactory { private static final Logger logger = LoggerFactory.getLogger(SslContextFactory.class); public static SslContext getSslContextForClient(Configuration config) throws SSLException, Exception { SslContext sslContext = SslContextBuilder.forClient().keyManager(getKeyManagerFactory(config)) .trustManager(getTrustManagerFactory(config)).build(); return sslContext; } public static SslContext getSslContextForServer(Configuration config) throws SSLException, Exception { SslContext sslContext = SslContextBuilder.forServer(getKeyManagerFactory(config)) .trustManager(getTrustManagerFactory(config)).build(); return sslContext; } public static KeyManagerFactory getKeyManagerFactory(Configuration sslConfig) throws Exception { final Configuration kdConfig = sslConfig.getChildren(KeyData.ordinal())[0]; final String keyManagerAlgo = kdConfig.getStringValue(KDManager.ordinal(), null); final String keyStoreType = kdConfig.getStringValue(KDStore.ordinal(), null); final String keyStorePassword = kdConfig.getStringValue(KDPwd.ordinal(), null); final String keyStoreFile = kdConfig.getStringValue(KDFile.ordinal(), null); logger.debug("keyManagerAlgo: {}", keyManagerAlgo); logger.debug("keyStoreType: {}", keyStoreType); logger.debug("keyStorePassword: {}", keyStorePassword); logger.debug("keyStoreFile: {}", keyStoreFile); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgo); KeyStore keyStore = KeyStore.getInstance(keyStoreType); char[] key = keyStorePassword.toCharArray(); keyStore.load(new FileInputStream(keyStoreFile), key); keyManagerFactory.init(keyStore, key); return keyManagerFactory; } public static TrustManagerFactory getTrustManagerFactory(Configuration sslConfig) throws Exception { final Configuration tdConfig = sslConfig.getChildren(TrustData.ordinal())[0]; final String trustManagerAlgo = tdConfig.getStringValue(TDManager.ordinal(), null); final String trustStoreType = tdConfig.getStringValue(TDStore.ordinal(), null); final String trustStorePassword = tdConfig.getStringValue(TDPwd.ordinal(), null); final String trustStoreFile = tdConfig.getStringValue(TDFile.ordinal(), null); logger.debug("trustManagerAlgo: {}", trustManagerAlgo); logger.debug("trustStoreType: {}", trustStoreType); logger.debug("trustStorePassword: {}", trustStorePassword); logger.debug("trustStoreFile: {}", trustStoreFile); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(trustManagerAlgo); KeyStore trustKeyStore = KeyStore.getInstance(trustStoreType); char[] trustKey = trustStorePassword.toCharArray(); trustKeyStore.load(new FileInputStream(trustStoreFile), trustKey); trustManagerFactory.init(trustKeyStore); return trustManagerFactory; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/StartTlsClientHandler.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import javax.net.ssl.SSLEngine; import org.jdiameter.client.impl.transport.tls.netty.TLSTransportClient.TlsHandshakingState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelPipeline; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslHandler; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class StartTlsClientHandler extends ChannelInboundHandlerAdapter { private static final Logger logger = LoggerFactory.getLogger(StartTlsClientHandler.class); private final TLSTransportClient tlsTransportClient; public StartTlsClientHandler(TLSTransportClient tlsTransportClient) { this.tlsTransportClient = tlsTransportClient; } @SuppressWarnings("unchecked") @Override public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception { logger.debug("StartTlsClientHandler"); ByteBuf buf = (ByteBuf) msg; byte[] bytes = new byte[buf.readableBytes()]; buf.getBytes(buf.readerIndex(), bytes); if ("StartTlsResponse".equals(new String(bytes))) { logger.debug("received StartTlsResponse"); SslContext sslContext = SslContextFactory.getSslContextForClient(this.tlsTransportClient.getConfig()); SSLEngine sslEngine = sslContext.newEngine(ctx.alloc()); sslEngine.setUseClientMode(true); SslHandler sslHandler = new SslHandler(sslEngine, false); final ChannelPipeline pipeline = ctx.pipeline(); pipeline.remove("startTlsClientHandler"); pipeline.addLast("sslHandler", sslHandler); logger.debug("StartTls starting handshake"); sslHandler.handshakeFuture().addListener(new GenericFutureListener() { @Override public void operationComplete(Future future) throws Exception { if (future.isSuccess()) { logger.debug("StartTls handshake succesfull"); tlsTransportClient.setTlsHandshakingState(TlsHandshakingState.SHAKEN); logger.debug("restoring all handlers"); pipeline.addLast("decoder", new DiameterMessageDecoder(StartTlsClientHandler.this.tlsTransportClient.getParent(), StartTlsClientHandler.this.tlsTransportClient.getParser())); pipeline.addLast("msgHandler", new DiameterMessageHandler(StartTlsClientHandler.this.tlsTransportClient.getParent(), true)); pipeline.addLast("encoder", new DiameterMessageEncoder(StartTlsClientHandler.this.tlsTransportClient.getParser())); pipeline.addLast("inbandWriter", new InbandSecurityHandler()); } } }); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.error(cause.getMessage(), cause); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/StartTlsInitiator.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Configuration; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.impl.transport.tls.netty.TLSTransportClient.TlsHandshakingState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelPipeline; import io.netty.util.ReferenceCountUtil; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class StartTlsInitiator extends ChannelInboundHandlerAdapter { private static final Logger logger = LoggerFactory.getLogger(StartTlsInitiator.class); private final Configuration config; private final TLSTransportClient tlsTransportClient; public StartTlsInitiator(Configuration config, TLSTransportClient tlsTransportClient) { this.config = config; this.tlsTransportClient = tlsTransportClient; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof IMessage) { IMessage m = (IMessage) msg; logger.debug("StartTlsInitiator"); if (m.getCommandCode() == IMessage.CAPABILITIES_EXCHANGE_ANSWER && this.tlsTransportClient.getTlsHandshakingState() == TlsHandshakingState.INIT) { AvpSet set = m.getAvps(); Avp inbandAvp = set.getAvp(Avp.INBAND_SECURITY_ID); if (inbandAvp != null && inbandAvp.getUnsigned32() == 1) { this.tlsTransportClient.setTlsHandshakingState(TlsHandshakingState.SHAKING); final ChannelPipeline pipeline = ctx.pipeline(); pipeline.remove("decoder"); pipeline.remove("msgHandler"); pipeline.remove(this); pipeline.remove("encoder"); pipeline.remove("inbandWriter"); pipeline.addLast("startTlsClientHandler", new StartTlsClientHandler(this.tlsTransportClient)); logger.debug("Sending StartTlsRequest"); ctx.writeAndFlush(Unpooled.wrappedBuffer("StartTlsRequest".getBytes())) .addListener(new GenericFutureListener() { @Override public void operationComplete(Future f) throws Exception { if (!f.isSuccess()) { logger.error(f.cause().getMessage(), f.cause()); } } }); } } } ReferenceCountUtil.release(msg); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.error(cause.getMessage(), cause); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/StartTlsServerHandler.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import javax.net.ssl.SSLEngine; import org.jdiameter.client.impl.transport.tls.netty.TLSTransportClient.TlsHandshakingState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelPipeline; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslHandler; import io.netty.util.ReferenceCountUtil; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class StartTlsServerHandler extends ChannelInboundHandlerAdapter { private static final Logger logger = LoggerFactory.getLogger(StartTlsServerHandler.class); private final TLSTransportClient tlsTransportClient; public StartTlsServerHandler(TLSTransportClient tlsTransportClient) { this.tlsTransportClient = tlsTransportClient; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { logger.debug("StartTlsServerHandler"); ByteBuf buf = (ByteBuf) msg; byte[] bytes = new byte[buf.readableBytes()]; buf.getBytes(buf.readerIndex(), bytes); if ("StartTlsRequest".equals(new String(bytes))) { logger.debug("Received StartTlsRequest"); SslContext sslContext = SslContextFactory.getSslContextForServer(this.tlsTransportClient.getConfig()); SSLEngine sslEngine = sslContext.newEngine(ctx.alloc()); sslEngine.setUseClientMode(false); SslHandler sslHandler = new SslHandler(sslEngine, false); final ChannelPipeline pipeline = ctx.pipeline(); pipeline.remove("decoder"); pipeline.remove("msgHandler"); pipeline.remove("encoder"); pipeline.remove("inbandWriter"); pipeline.remove(this); pipeline.addLast("sslHandler", sslHandler); sslHandler.handshakeFuture().addListener(new GenericFutureListener() { @Override public void operationComplete(Future future) throws Exception { if (future.isSuccess()) { logger.debug("StartTls server handshake succesfull"); tlsTransportClient.setTlsHandshakingState(TlsHandshakingState.SHAKEN); logger.debug("restoring all handlers"); pipeline.addLast("decoder", new DiameterMessageDecoder(StartTlsServerHandler.this.tlsTransportClient.getParent(), StartTlsServerHandler.this.tlsTransportClient.getParser())); pipeline.addLast("msgHandler", new DiameterMessageHandler(StartTlsServerHandler.this.tlsTransportClient.getParent(), true)); pipeline.addLast("encoder", new DiameterMessageEncoder(StartTlsServerHandler.this.tlsTransportClient.getParser())); pipeline.addLast("inbandWriter", new InbandSecurityHandler()); } } }); ReferenceCountUtil.release(msg); logger.debug("Sending StartTlsResponse"); ctx.writeAndFlush(Unpooled.wrappedBuffer("StartTlsResponse".getBytes())).addListener(new GenericFutureListener() { @Override public void operationComplete(Future f) throws Exception { if (!f.isSuccess()) { logger.error(f.cause().getMessage(), f.cause()); } } }); } else { ctx.fireChannelRead(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.error(cause.getMessage(), cause); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/TLSClientConnection.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import javax.net.ssl.SSLSocketFactory; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.io.IConnection; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.TransportError; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.transport.tls.TLSUtils; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.server.impl.helpers.Parameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.channel.Channel; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class TLSClientConnection implements IConnection { private static Logger logger = LoggerFactory.getLogger(TLSClientConnection.class); private TLSTransportClient client; private SSLSocketFactory factory; private Configuration sslConfig; private final long createdTime = System.currentTimeMillis(); private LinkedBlockingQueue buffer = new LinkedBlockingQueue(64); private Lock lock = new ReentrantLock(); private ConcurrentLinkedQueue listeners = new ConcurrentLinkedQueue(); // Cached value for connection key private String cachedKey = null; public TLSClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IMessageParser parser, String ref) throws Exception { String secRef = ref; if (secRef == null) { if (!config.isAttributeExist(Parameters.SecurityRef.ordinal())) { throw new IllegalArgumentException("No security_ref attribute present in local peer!"); } else { secRef = config.getStringValue(Parameters.SecurityRef.ordinal(), ""); } } this.sslConfig = TLSUtils.getSSLConfiguration(config, secRef); this.client = new TLSTransportClient(this, concurrentFactory, parser, sslConfig, new InetSocketAddress(remoteAddress, remotePort), new InetSocketAddress(localAddress, localPort)); // this.client.start(); } public TLSClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IConnectionListener listener, IMessageParser parser, String ref) throws InterruptedException { this.listeners.add(listener); String secRef = ref; if (secRef == null) { if (!config.isAttributeExist(Parameters.SecurityRef.ordinal())) { throw new IllegalArgumentException("No security_ref attribute present in local peer!"); } else { secRef = config.getStringValue(Parameters.SecurityRef.ordinal(), ""); } } this.sslConfig = TLSUtils.getSSLConfiguration(config, secRef); this.client = new TLSTransportClient(this, concurrentFactory, parser, sslConfig, new InetSocketAddress(remoteAddress, remotePort), new InetSocketAddress(localAddress, localPort)); // this.client.start(); } public TLSClientConnection(Configuration config, Configuration localPeerSSLConfig, IConcurrentFactory concurrentFactory, IMessageParser parser, Channel channel) throws Exception { if (localPeerSSLConfig == null) { throw new IllegalArgumentException("Can not create connection without TLS parameters"); } this.sslConfig = localPeerSSLConfig; this.client = new TLSTransportClient(this, concurrentFactory, parser, sslConfig, channel); // this.client.start(); } protected TLSTransportClient getClient() { return client; } public Configuration getSSLConfig() { return sslConfig; } public SSLSocketFactory getSSLFactory() { return factory; } public long getCreatedTime() { return createdTime; } public InetAddress getRemoteAddress() { return getClient().getDestAddress().getAddress(); } public int getRemotePort() { return getClient().getDestAddress().getPort(); } public void addConnectionListener(IConnectionListener listener) { lock.lock(); try { listeners.add(listener); if (buffer.size() != 0) { for (Event e : buffer) { try { onEvent(e); } catch (AvpDataException e1) { // ignore } } buffer.clear(); } } finally { lock.unlock(); } } public void remAllConnectionListener() { lock.lock(); try { listeners.clear(); } finally { lock.unlock(); } } public void remConnectionListener(IConnectionListener listener) { lock.lock(); try { listeners.remove(listener); } finally { lock.unlock(); } } public void release() throws IOException { try { if (getClient() != null) { getClient().release(); } } catch (Exception e) { throw new IOException(e.getMessage()); } finally { buffer.clear(); remAllConnectionListener(); } } public boolean isWrapperFor(Class aClass) throws InternalException { return false; } public T unwrap(Class aClass) throws InternalException { return null; } public boolean isConnected() { return getClient() != null && getClient().isConnected(); } public boolean isNetworkInitiated() { return false; } public String getKey() { if (this.cachedKey == null) { this.cachedKey = new StringBuffer("aaas://").append(getRemoteAddress().getHostName()).append(":") .append(getRemotePort()) .toString(); } return this.cachedKey; } public void connect() throws TransportException { try { // getClient().initialize(); getClient().start(); } catch (Exception e) { throw new TransportException("Cannot init transport: ", TransportError.Internal, e); } } public void disconnect() throws InternalError { try { if (getClient() != null) { getClient().stop(); } } catch (Exception e) { throw new InternalError("Error while stopping transport: " + e.getMessage()); } } public void sendMessage(IMessage message) throws TransportException, OverloadException { try { if (getClient() != null) { getClient().sendMessage(message); } } catch (Exception e) { throw new TransportException("Cannot send message: ", TransportError.FailedSendMessage, e); } } protected void onDisconnect() throws AvpDataException { onEvent(new Event(EventType.DISCONNECTED)); } protected void onMessageReceived(IMessage message) throws AvpDataException { // if (logger.isDebugEnabled()) { // logger.debug("Received message of size [{}]", message.array().length); // } onEvent(new Event(EventType.MESSAGE_RECEIVED, message)); } protected void onAvpDataException(AvpDataException e) { try { onEvent(new Event(EventType.DATA_EXCEPTION, e)); } catch (AvpDataException e1) { // ignore } } protected void onConnected() { try { onEvent(new Event(EventType.CONNECTED)); } catch (AvpDataException e1) { // ignore } } protected void onEvent(Event event) throws AvpDataException { lock.lock(); try { if (processBufferedMessages(event)) { for (IConnectionListener listener : listeners) { switch (event.type) { case CONNECTED: listener.connectionOpened(getKey()); break; case DISCONNECTED: listener.connectionClosed(getKey(), null); break; case MESSAGE_RECEIVED: listener.messageReceived(getKey(), event.message); break; case DATA_EXCEPTION: listener.internalError(getKey(), null, new TransportException("Avp Data Exception:", TransportError.ReceivedBrokenMessage, event.exception)); break; } } } } finally { lock.unlock(); } } protected boolean processBufferedMessages(Event event) throws AvpDataException { if (listeners.size() == 0) { try { buffer.add(event); } catch (IllegalStateException e) { // FIXME : requires JDK6 : buffer.removeLast(); Event[] tempBuffer = buffer.toArray(new Event[buffer.size()]); buffer.remove(tempBuffer[tempBuffer.length - 1]); buffer.add(event); } return false; } else { return true; } } // --------------------- helper classes ---------------------- private enum EventType { CONNECTED, DISCONNECTED, MESSAGE_RECEIVED, DATA_EXCEPTION } private static class Event { EventType type; IMessage message; Exception exception; Event(EventType type) { this.type = type; } Event(EventType type, Exception exception) { this(type); this.exception = exception; } Event(EventType type, IMessage message) { this(type); this.message = message; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/transport/tls/netty/TLSTransportClient.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.transport.tls.netty; import java.io.IOException; import java.net.InetSocketAddress; import org.jdiameter.api.Configuration; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class TLSTransportClient { private static final Logger logger = LoggerFactory.getLogger(TLSTransportClient.class); private TLSClientConnection parentConnection; private IConcurrentFactory concurrentFactory; private IMessageParser parser; private Configuration config; private InetSocketAddress destAddress; private InetSocketAddress origAddress; private String socketDescription = null; private Channel channel; private EventLoopGroup workerGroup; private volatile TlsHandshakingState tlsHandshakingState = TlsHandshakingState.INIT; enum TlsHandshakingState { INIT, SHAKING, SHAKEN } protected TLSTransportClient(TLSClientConnection parenConnection, IConcurrentFactory concurrentFactory, IMessageParser parser, Configuration config) { this.parentConnection = parenConnection; this.concurrentFactory = concurrentFactory; this.parser = parser; this.config = config; } public TLSTransportClient(TLSClientConnection parenConnection, IConcurrentFactory concurrentFactory, IMessageParser parser, Configuration config, InetSocketAddress destAddress, InetSocketAddress origAddress) { this(parenConnection, concurrentFactory, parser, config); if (destAddress == null) { throw new IllegalArgumentException("Destination address is required"); } this.destAddress = destAddress; this.origAddress = origAddress; this.socketDescription = origAddress.toString() + "->" + destAddress.toString(); logger.debug("Created TLSTransportClient (client) for {}", socketDescription); } public TLSTransportClient(TLSClientConnection parenConnection, IConcurrentFactory concurrentFactory, IMessageParser parser, Configuration config, Channel channel) { this(parenConnection, concurrentFactory, parser, config); if (channel == null) { throw new IllegalArgumentException("Channel is required"); } this.channel = channel; this.origAddress = (InetSocketAddress) this.channel.localAddress(); this.destAddress = (InetSocketAddress) this.channel.remoteAddress(); this.socketDescription = origAddress.toString() + "->" + destAddress.toString(); ChannelPipeline pipeline = this.channel.pipeline(); pipeline.addLast("startTlsServerHandler", new StartTlsServerHandler(this)); pipeline.addLast("decoder", new DiameterMessageDecoder(parenConnection, parser)); pipeline.addLast("msgHandler", new DiameterMessageHandler(parentConnection, true)); pipeline.addLast("encoder", new DiameterMessageEncoder(parser)); pipeline.addLast("inbandWriter", new InbandSecurityHandler()); logger.debug("Created TLSTransportClient (server) for {}", socketDescription); } // only client side public void start() throws InterruptedException { logger.debug("Staring client TLSTransportClient {} ", socketDescription); if (isConnected()) { logger.debug("Already connected TLSTransportClient {} ", socketDescription); return; } workerGroup = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(workerGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel channel) throws Exception { ChannelPipeline pipeline = channel.pipeline(); pipeline.addLast("decoder", new DiameterMessageDecoder(parentConnection, parser)); pipeline.addLast("msgHandler", new DiameterMessageHandler(parentConnection, false)); pipeline.addLast("startTlsInitiator", new StartTlsInitiator(config, TLSTransportClient.this)); pipeline.addLast("encoder", new DiameterMessageEncoder(parser)); pipeline.addLast("inbandWriter", new InbandSecurityHandler()); } }); this.channel = bootstrap.remoteAddress(destAddress).connect().sync().channel(); parentConnection.onConnected(); logger.debug("Started TLS Transport on Socket {}", socketDescription); } public TLSClientConnection getParent() { return parentConnection; } public InetSocketAddress getDestAddress() { return this.destAddress; } public void setDestAddress(InetSocketAddress address) { this.destAddress = address; if (logger.isDebugEnabled()) { logger.debug("Destination address is set to [{}] : [{}]", destAddress.getHostName(), destAddress.getPort()); } } public void setOrigAddress(InetSocketAddress address) { this.origAddress = address; if (logger.isDebugEnabled()) { logger.debug("Origin address is set to [{}] : [{}]", origAddress.getHostName(), origAddress.getPort()); } } public InetSocketAddress getOrigAddress() { return this.origAddress; } void sendMessage(IMessage message) throws IOException { if (!isConnected()) { throw new IOException("Failed to send message over [" + socketDescription + "]"); } if (this.tlsHandshakingState == TlsHandshakingState.SHAKING) { return; } logger.debug("About to send a message over the TLS socket [{}]", socketDescription); channel.writeAndFlush(message); } boolean isConnected() { return this.channel != null && this.channel.isActive(); } public void stop() { //logger.debug("Stopping TLS Transport {}", socketDescription); closeChannel(); closeWorkerGroup(); //logger.debug("TLS Transport is stopped {}", socketDescription); getParent().disconnect(); } public void release() throws Exception { stop(); destAddress = null; origAddress = null; } private void closeChannel() { if (channel != null && channel.isActive()) { try { channel.closeFuture().sync(); } catch (InterruptedException e) { logger.error("Error stopping socket " + socketDescription, e); } channel = null; } } private void closeWorkerGroup() { if (workerGroup != null && !workerGroup.isShuttingDown()) { try { workerGroup.shutdownGracefully().sync(); } catch (InterruptedException e) { logger.error("Error stopping socket " + socketDescription, e); } workerGroup = null; } } public TlsHandshakingState getTlsHandshakingState() { return tlsHandshakingState; } public void setTlsHandshakingState(TlsHandshakingState tlsHandshakingState) { this.tlsHandshakingState = tlsHandshakingState; } public TLSClientConnection getParentConnection() { return parentConnection; } public IMessageParser getParser() { return parser; } public Configuration getConfig() { return config; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/AppSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app; import org.jdiameter.api.ApplicationId; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public abstract class AppSessionDataLocalImpl implements IAppSessionData { private String sessionId; private ApplicationId applicationId; @Override public String getSessionId() { return sessionId; } public void setSessionId(String sessionId) { this.sessionId = sessionId; } @Override public ApplicationId getApplicationId() { return applicationId; } @Override public void setApplicationId(ApplicationId applicationId) { this.applicationId = applicationId; } @Override public boolean remove() { return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((applicationId == null) ? 0 : applicationId.hashCode()); result = prime * result + ((sessionId == null) ? 0 : sessionId.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } AppSessionDataLocalImpl other = (AppSessionDataLocalImpl) obj; if (applicationId == null) { if (other.applicationId != null) { return false; } } else if (!applicationId.equals(other.applicationId)) { return false; } if (sessionId == null) { if (other.sessionId != null) { return false; } } else if (!sessionId.equals(other.sessionId)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/IAppSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app; import org.jdiameter.api.ApplicationId; /** * Interface for Application Session Data * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAppSessionData { int NON_INITIALIZED = Integer.MIN_VALUE; /** * Returns the session-id of the session to which this data belongs to. * * @return a string representing the session-id */ String getSessionId(); /** * Sets the Application-Id of this Session Data session to which this data belongs to. * * @param applicationId the Application-Id */ void setApplicationId(ApplicationId applicationId); /** * Returns the Application-Id of this Session Data session to which this data belongs to. * * @return the Application-Id */ ApplicationId getApplicationId(); /** * Removes this session data from storage * * @return true if removed, false otherwise */ boolean remove(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/IAppSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app; import org.jdiameter.api.app.AppSession; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAppSessionDataFactory { T getAppSessionData(Class clazz, String sessionId); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/IAppSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.app.AppSession; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAppSessionFactory { AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args); AppSession getSession(String sessionId, Class aClass); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/IAppSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAppSessionState { int getValue(); T fromInt(int val) throws IllegalArgumentException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/acc/ClientAccSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.acc; import org.jdiameter.common.api.app.IAppSessionState; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ public enum ClientAccSessionState implements IAppSessionState { IDLE(0), OPEN(1), PENDING_EVENT(2), PENDING_START(3), PENDING_INTERIM(4), PENDING_CLOSE(5), PENDING_BUFFERED(6); private final int value; ClientAccSessionState(int val) { value = val; } @Override public final int getValue() { return value; } @Override public final ClientAccSessionState fromInt(int val) throws IllegalArgumentException { switch (val) { case 0: return IDLE; case 1: return OPEN; case 2: return PENDING_EVENT; case 3: return PENDING_START; case 4: return PENDING_INTERIM; case 5: return PENDING_CLOSE; case 6: return PENDING_BUFFERED; default: throw new IllegalArgumentException(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/acc/IAccMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.acc; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Request; import org.jdiameter.api.acc.events.AccountAnswer; import org.jdiameter.api.acc.events.AccountRequest; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IAccMessageFactory { ApplicationId getApplicationId(); int getAccMessageCommandCode(); AccountRequest createAccRequest(Request request); AccountAnswer createAccAnswer(Answer answer); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/acc/IAccSessionData.java ================================================ /* * 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.jdiameter.common.api.app.acc; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAccSessionData extends IAppSessionData { // marker interface } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/acc/IAccSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.acc; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.acc.ClientAccSessionListener; import org.jdiameter.api.acc.ServerAccSessionListener; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAccSessionFactory extends IAppSessionFactory { /** * @return the serverSessionListener */ ServerAccSessionListener getServerSessionListener(); /** * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerAccSessionListener serverSessionListener); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); /** * @return the clientSessionListener */ ClientAccSessionListener getClientSessionListener(); /** * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientAccSessionListener clientSessionListener); /** * @return the clientContextListener */ IClientAccActionContext getClientContextListener(); /** * @param clientContextListener the clientContextListener to set */ void setClientContextListener(IClientAccActionContext clientContextListener); /** * @return the serverContextListener */ IServerAccActionContext getServerContextListener(); /** * @param serverContextListener the serverContextListener to set */ void setServerContextListener(IServerAccActionContext serverContextListener); void setMessageFactory(IAccMessageFactory messageFactory); IAccMessageFactory getMessageFactory(); ApplicationId getApplicationId(); void setApplicationId(ApplicationId id); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/acc/IClientAccActionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.acc; import org.jdiameter.api.InternalException; import org.jdiameter.api.Request; import org.jdiameter.api.acc.ClientAccSession; /** * Diameter Accounting Client Additional listener Actions for FSM * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IClientAccActionContext { /** * Filling nested avp into interim message * * @param interimRequest instance of interim message which will be sent to server */ void interimIntervalElapses(ClientAccSession appSession, Request interimRequest) throws InternalException; /** * Call back for failed_send_record event * * @param accRequest accounting request record * * @return true if you want put message to buffer and false if you want to stop processing */ boolean failedSendRecord(ClientAccSession appSession, Request accRequest) throws InternalException; /** * Filling nested avp into STR * * @param sessionTermRequest instance of STR which will be sent to server */ void disconnectUserOrDev(ClientAccSession appSession, Request sessionTermRequest) throws InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/acc/IServerAccActionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.acc; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.InternalException; import org.jdiameter.api.acc.ServerAccSession; /** * Diameter Accounting Server Additional listener Actions for FSM * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerAccActionContext { void sessionTimerStarted(ServerAccSession appSession, ScheduledFuture timer) throws InternalException; void sessionTimeoutElapses(ServerAccSession appSession) throws InternalException; void sessionTimerCanceled(ServerAccSession appSession, ScheduledFuture timer) throws InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/acc/ServerAccSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.acc; import org.jdiameter.common.api.app.IAppSessionState; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ public enum ServerAccSessionState implements IAppSessionState { IDLE(0), OPEN(1); private final int value; ServerAccSessionState(int val) { value = val; } @Override public final int getValue() { return value; } @Override public final ServerAccSessionState fromInt(int val) throws IllegalArgumentException { switch (val) { case 0: return IDLE; case 1: return OPEN; default: throw new IllegalArgumentException(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/auth/ClientAuthSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.auth; import org.jdiameter.common.api.app.IAppSessionState; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ public enum ClientAuthSessionState implements IAppSessionState { IDLE(0), OPEN(1), PENDING(2), DISCONNECTED(3); private final int value; ClientAuthSessionState(int val) { value = val; } @Override public final int getValue() { return value; } @Override public final ClientAuthSessionState fromInt(int val) throws IllegalArgumentException { switch (val) { case 0: return IDLE; case 1: return OPEN; case 2: return PENDING; case 3: return DISCONNECTED; default: throw new IllegalArgumentException(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/auth/IAuthMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.auth; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IAuthMessageFactory { ApplicationId getApplicationId(); int getAuthMessageCommandCode(); AppRequestEvent createAuthRequest(Request request); AppAnswerEvent createAuthAnswer(Answer answer); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/auth/IAuthSessionData.java ================================================ /* * 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.jdiameter.common.api.app.auth; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAuthSessionData extends IAppSessionData { //marker interface } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/auth/IAuthSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.auth; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.auth.ClientAuthSessionListener; import org.jdiameter.api.auth.ServerAuthSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * Interface for Diameter Authentication Session Factories * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAuthSessionFactory extends IAppSessionFactory { IAuthMessageFactory getMessageFactory(); void setMessageFactory(IAuthMessageFactory v); ServerAuthSessionListener getServerSessionListener(); void setServerSessionListener(ServerAuthSessionListener v); StateChangeListener getStateListener(); void setStateListener(StateChangeListener v); ClientAuthSessionListener getClientSessionListener(); void setClientSessionListener(ClientAuthSessionListener v); IServerAuthActionContext getServerSessionContext(); void setServerSessionContext(IServerAuthActionContext v); IClientAuthActionContext getClientSessionContext(); void setClientSessionContext(IClientAuthActionContext v); boolean isStateles(); void setStateles(boolean stateless); /** * @return the messageTimeout */ long getMessageTimeout(); /** * @param messageTimeout the messageTimeout to set */ void setMessageTimeout(long messageTimeout); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/auth/IClientAuthActionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.auth; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.auth.ClientAuthSession; /** * Diameter Authorization Client Additional listener Actions for FSM * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientAuthActionContext { long getAccessTimeout() throws InternalException; void accessTimeoutElapses(ClientAuthSession session) throws InternalException; void disconnectUserOrDev(ClientAuthSession session, Message request) throws InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/auth/IServerAuthActionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.auth; import org.jdiameter.api.InternalException; import org.jdiameter.api.auth.ServerAuthSession; /** * Diameter Authorization Server Additional listener Actions for FSM * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerAuthActionContext { long getAccessTimeout() throws InternalException; void accessTimeoutElapses(ServerAuthSession session) throws InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/auth/ServerAuthSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.auth; import org.jdiameter.common.api.app.IAppSessionState; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ public enum ServerAuthSessionState implements IAppSessionState { IDLE(0), OPEN(1), DISCONNECTED(2); private final int value; ServerAuthSessionState(int val) { value = val; } @Override public final int getValue() { return value; } @Override public final ServerAuthSessionState fromInt(int val) throws IllegalArgumentException { switch (val) { case 0: return IDLE; case 1: return OPEN; case 2: return DISCONNECTED; default: throw new IllegalArgumentException(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cca/ClientCCASessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cca; import org.jdiameter.common.api.app.IAppSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public enum ClientCCASessionState implements IAppSessionState { IDLE(0), PENDING_EVENT(1), PENDING_INITIAL(2), PENDING_UPDATE(3), PENDING_TERMINATION(4), PENDING_BUFFERED(5), OPEN(6); private int stateValue; ClientCCASessionState(int stateV) { this.stateValue = stateV; } @Override public ClientCCASessionState fromInt(int v) throws IllegalArgumentException { switch (v) { case 0: return IDLE; case 1: return PENDING_EVENT; case 2: return PENDING_INITIAL; case 3: return PENDING_UPDATE; case 4: return PENDING_TERMINATION; case 5: return PENDING_BUFFERED; case 6: return OPEN; default: throw new IllegalArgumentException("Illegal value of int representation!!!!"); } } @Override public int getValue() { return stateValue; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cca/ICCAMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cca; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; /** * Diameter Credit-Control Application Message Factory * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ICCAMessageFactory { ReAuthRequest createReAuthRequest(Request request); ReAuthAnswer createReAuthAnswer(Answer answer); JCreditControlRequest createCreditControlRequest(Request request); JCreditControlAnswer createCreditControlAnswer(Answer answer); long[] getApplicationIds(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cca/ICCASessionData.java ================================================ /* * JBoss, Home of Professional Open Source * Copyright 2008, 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.jdiameter.common.api.app.cca; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ICCASessionData extends IAppSessionData { // marker interface } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cca/ICCASessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cca; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.cca.ClientCCASessionListener; import org.jdiameter.api.cca.ServerCCASessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * Session Factory interface for Diameter Credit-Control Application (CCA). * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ICCASessionFactory extends IAppSessionFactory { /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the clientSessionListener */ ClientCCASessionListener getClientSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientCCASessionListener clientSessionListener); /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the serverSessionListener */ ServerCCASessionListener getServerSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerCCASessionListener serverSessionListener); /** * @return the serverContextListener */ IServerCCASessionContext getServerContextListener(); /** * @param serverContextListener the serverContextListener to set */ void setServerContextListener(IServerCCASessionContext serverContextListener); /** * @return the clientContextListener */ IClientCCASessionContext getClientContextListener(); /** * @return the messageFactory */ ICCAMessageFactory getMessageFactory(); /** * @param messageFactory the messageFactory to set */ void setMessageFactory(ICCAMessageFactory messageFactory); /** * @param clientContextListener the clientContextListener to set */ void setClientContextListener(IClientCCASessionContext clientContextListener); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cca/IClientCCASessionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cca; import org.jdiameter.api.Message; import org.jdiameter.api.cca.ClientCCASession; /** * Diameter Credit Control Application Client Additional listener Actions for FSM * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientCCASessionContext { long getDefaultTxTimerValue(); void txTimerExpired(ClientCCASession session); int getDefaultCCFHValue(); int getDefaultDDFHValue(); void grantAccessOnDeliverFailure(ClientCCASession clientCCASessionImpl, Message request); void denyAccessOnDeliverFailure(ClientCCASession clientCCASessionImpl, Message request); void grantAccessOnTxExpire(ClientCCASession clientCCASessionImpl); void denyAccessOnTxExpire(ClientCCASession clientCCASessionImpl); void grantAccessOnFailureMessage(ClientCCASession clientCCASessionImpl); void denyAccessOnFailureMessage(ClientCCASession clientCCASessionImpl); void indicateServiceError(ClientCCASession clientCCASessionImpl); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cca/IServerCCASessionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cca; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.Request; import org.jdiameter.api.cca.ServerCCASession; /** * Diameter Credit Control Application Server Additional listener Actions for FSM * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerCCASessionContext { void sessionSupervisionTimerExpired(ServerCCASession session); /** * This is called always when Tcc starts * * @param session * @param future */ void sessionSupervisionTimerStarted(ServerCCASession session, ScheduledFuture future); void sessionSupervisionTimerReStarted(ServerCCASession session, ScheduledFuture future); void sessionSupervisionTimerStopped(ServerCCASession session, ScheduledFuture future); /** * Returns seconds value representing default validity time, App session uses 2x for Tcc timer * * @return */ long getDefaultValidityTime(); void timeoutExpired(Request request); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cca/ServerCCASessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cca; import org.jdiameter.common.api.app.IAppSessionState; /** * Diameter Credit-Control Application Server states * * @author Bartosz Baranowski * @author Alexandre Mendonca */ public enum ServerCCASessionState implements IAppSessionState { IDLE(0), OPEN(1); private int stateRepresentation; ServerCCASessionState(int v) { this.stateRepresentation = v; } @Override public ServerCCASessionState fromInt(int v) throws IllegalArgumentException { switch (v) { case 0: return IDLE; case 1: return OPEN; default: throw new IllegalArgumentException("Illegal value of int representation!!!!"); } } @Override public int getValue() { return stateRepresentation; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cxdx/CxDxSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cxdx; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public enum CxDxSessionState { //FIXME: should we distinguish types of messages? IDLE, MESSAGE_SENT_RECEIVED, TERMINATED, TIMEDOUT; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cxdx/ICxDxMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cxdx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.cxdx.events.JLocationInfoAnswer; import org.jdiameter.api.cxdx.events.JLocationInfoRequest; import org.jdiameter.api.cxdx.events.JMultimediaAuthAnswer; import org.jdiameter.api.cxdx.events.JMultimediaAuthRequest; import org.jdiameter.api.cxdx.events.JPushProfileAnswer; import org.jdiameter.api.cxdx.events.JPushProfileRequest; import org.jdiameter.api.cxdx.events.JRegistrationTerminationAnswer; import org.jdiameter.api.cxdx.events.JRegistrationTerminationRequest; import org.jdiameter.api.cxdx.events.JServerAssignmentAnswer; import org.jdiameter.api.cxdx.events.JServerAssignmentRequest; import org.jdiameter.api.cxdx.events.JUserAuthorizationAnswer; import org.jdiameter.api.cxdx.events.JUserAuthorizationRequest; /** * Message Factory for Diameter Cx/Dx application. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ICxDxMessageFactory { /** * Creates a Location-Info-Request event. * * @param request the request to create the LIR from * * @return an AppRequestEvent wrapping the LIR */ JLocationInfoRequest createLocationInfoRequest(Request request); /** * Creates a User-Authorization-Request event. * * @param request the request to create the UAR from * * @return an AppRequestEvent wrapping the UAR */ JUserAuthorizationRequest createUserAuthorizationRequest(Request request); /** * Creates a Server-Assignment-Request event. * * @param request the request to create the SAR from * * @return an AppRequestEvent wrapping the SAR */ JServerAssignmentRequest createServerAssignmentRequest(Request request); /** * Creates a Registration-Termination-Request event. * * @param request the request to create the RTR from * * @return an AppRequestEvent wrapping the RTR */ JRegistrationTerminationRequest createRegistrationTerminationRequest(Request request); /** * Creates a Multimedia-Auth-Request event. * * @param request the request to create the MAR from * * @return an AppRequestEvent wrapping the MAR */ JMultimediaAuthRequest createMultimediaAuthRequest(Request request); /** * Creates a Push-Profile-Request event. * * @param request the request to create the PPR from * * @return an AppRequestEvent wrapping the PPR */ JPushProfileRequest createPushProfileRequest(Request request); /** * Creates a Push-Profile-Answer event. * * @param answer the answer to create the PPA from * * @return an AppAnswerEvent wrapping the PPA */ JPushProfileAnswer createPushProfileAnswer(Answer answer); /** * Creates a Location-Info-Answer event. * * @param answer the answer to create the LIA from * * @return an AppAnswerEvent wrapping the LIA */ JLocationInfoAnswer createLocationInfoAnswer(Answer answer); /** * Creates a User-Authorization-Answer event. * * @param answer the answer to create the UAA from * * @return an AppAnswerEvent wrapping the UAA */ JUserAuthorizationAnswer createUserAuthorizationAnswer(Answer answer); /** * Creates a Server-Assignment-Answer event. * * @param answer the answer to create the SAA from * * @return an AppAnswerEvent wrapping the SAA */ JServerAssignmentAnswer createServerAssignmentAnswer(Answer answer); /** * Creates a Registration-Termination-Answer event. * * @param answer the answer to create the RTA from * * @return an AppAnswerEvent wrapping the RTA */ JRegistrationTerminationAnswer createRegistrationTerminationAnswer(Answer answer); /** * Creates a Multimedia-Auth-Answer event. * * @param answer the answer to create the MAA from * * @return an AppAnswerEvent wrapping the MAA */ JMultimediaAuthAnswer createMultimediaAuthAnswer(Answer answer); /** * Returns the Application-Id that this message factory is related to * * @return the Application-Id value */ long getApplicationId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cxdx/ICxDxSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cxdx; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface ICxDxSessionData extends IAppSessionData { void setCxDxSessionState(CxDxSessionState state); CxDxSessionState getCxDxSessionState(); Serializable getTsTimerId(); void setTsTimerId(Serializable tid); void setBuffer(Request buffer); Request getBuffer(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/cxdx/ICxDxSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.cxdx; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.cxdx.ClientCxDxSessionListener; import org.jdiameter.api.cxdx.ServerCxDxSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * Session Factory interface for Diameter CxDx application. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ICxDxSessionFactory extends IAppSessionFactory { /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the clientSessionListener */ ClientCxDxSessionListener getClientSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientCxDxSessionListener clientSessionListener); /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the serverSessionListener */ ServerCxDxSessionListener getServerSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerCxDxSessionListener serverSessionListener); /** * @return the messageFactory */ ICxDxMessageFactory getMessageFactory(); /** * @param messageFactory the messageFactory to set */ void setMessageFactory(ICxDxMessageFactory messageFactory); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/gx/ClientGxSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.gx; import org.jdiameter.common.api.app.IAppSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca * @author Erick Svenson */ public enum ClientGxSessionState implements IAppSessionState { IDLE(0), PENDING_EVENT(1), PENDING_INITIAL(2), PENDING_UPDATE(3), PENDING_TERMINATION(4), PENDING_BUFFERED(5), OPEN(6); private int stateValue; ClientGxSessionState(int stateV) { this.stateValue = stateV; } @Override public ClientGxSessionState fromInt(int v) throws IllegalArgumentException { switch (v) { case 0: return IDLE; case 1: return PENDING_EVENT; case 2: return PENDING_INITIAL; case 3: return PENDING_UPDATE; case 4: return PENDING_TERMINATION; case 5: return PENDING_BUFFERED; case 6: return OPEN; default: throw new IllegalArgumentException("Illegal value of int representation!!!!"); } } @Override public int getValue() { return stateValue; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/gx/IClientGxSessionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.gx; import org.jdiameter.api.Message; import org.jdiameter.api.gx.ClientGxSession; /** * Diameter Gx Application Client Additional listener. Actions for FSM * * @author Bartosz Baranowski * @author Alexandre Mendonca * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface IClientGxSessionContext { long getDefaultTxTimerValue(); void txTimerExpired(ClientGxSession session); int getDefaultCCFHValue(); int getDefaultDDFHValue(); void grantAccessOnDeliverFailure(ClientGxSession clientGxSessionImpl, Message request); void denyAccessOnDeliverFailure(ClientGxSession clientGxSessionImpl, Message request); void grantAccessOnTxExpire(ClientGxSession clientGxSessionImpl); void denyAccessOnTxExpire(ClientGxSession clientGxSessionImpl); void grantAccessOnFailureMessage(ClientGxSession clientGxSessionImpl); void denyAccessOnFailureMessage(ClientGxSession clientGxSessionImpl); void indicateServiceError(ClientGxSession clientGxSessionImpl); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/gx/IGxMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.gx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.gx.events.GxCreditControlAnswer; import org.jdiameter.api.gx.events.GxCreditControlRequest; import org.jdiameter.api.gx.events.GxReAuthAnswer; import org.jdiameter.api.gx.events.GxReAuthRequest; /** * Diameter Gx Application Message Factory * * @author Bartosz Baranowski * @author Alexandre Mendonca * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface IGxMessageFactory { GxReAuthRequest createGxReAuthRequest(Request request); GxReAuthAnswer createGxReAuthAnswer(Answer answer); GxCreditControlRequest createCreditControlRequest(Request request); GxCreditControlAnswer createCreditControlAnswer(Answer answer); long[] getApplicationIds(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/gx/IGxSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.gx; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IGxSessionData extends IAppSessionData { // marker interface } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/gx/IGxSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.gx; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.gx.ClientGxSessionListener; import org.jdiameter.api.gx.ServerGxSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * Session Factory interface for Diameter Gx Application (Gx). * * @author Bartosz Baranowski * @author Alexandre Mendonca * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public interface IGxSessionFactory extends IAppSessionFactory { /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the clientSessionListener */ ClientGxSessionListener getClientSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientGxSessionListener clientSessionListener); /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the serverSessionListener */ ServerGxSessionListener getServerSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerGxSessionListener serverSessionListener); /** * @return the serverContextListener */ IServerGxSessionContext getServerContextListener(); /** * @param serverContextListener the serverContextListener to set */ void setServerContextListener(IServerGxSessionContext serverContextListener); /** * @return the clientContextListener */ IClientGxSessionContext getClientContextListener(); /** * @return the messageFactory */ IGxMessageFactory getMessageFactory(); /** * @param messageFactory the messageFactory to set */ void setMessageFactory(IGxMessageFactory messageFactory); /** * @param clientContextListener the clientContextListener to set */ void setClientContextListener(IClientGxSessionContext clientContextListener); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/gx/IServerGxSessionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.gx; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.Request; import org.jdiameter.api.gx.ServerGxSession; /** * Diameter Gx Application Server Additional listener Actions for FSM * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerGxSessionContext { void sessionSupervisionTimerExpired(ServerGxSession session); /** * This is called always when Tcc starts * * @param session * @param future */ void sessionSupervisionTimerStarted(ServerGxSession session, ScheduledFuture future); void sessionSupervisionTimerReStarted(ServerGxSession session, ScheduledFuture future); void sessionSupervisionTimerStopped(ServerGxSession session, ScheduledFuture future); /** * Returns seconds value representing default validity time, App session uses 2x for Tcc timer * * @return */ long getDefaultValidityTime(); void timeoutExpired(Request request); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/gx/ServerGxSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.gx; import org.jdiameter.common.api.app.IAppSessionState; /** * Diameter Gx Server states * * @author Bartosz Baranowski * @author Alexandre Mendonca */ public enum ServerGxSessionState implements IAppSessionState { IDLE(0), OPEN(1); private int stateRepresentation; ServerGxSessionState(int v) { this.stateRepresentation = v; } @Override public ServerGxSessionState fromInt(int v) throws IllegalArgumentException { switch (v) { case 0: return IDLE; case 1: return OPEN; default: throw new IllegalArgumentException("Illegal value of int representation!!!!"); } } @Override public int getValue() { return stateRepresentation; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rf/ClientRfSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rf; import org.jdiameter.common.api.app.IAppSessionState; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ public enum ClientRfSessionState implements IAppSessionState { IDLE(0), OPEN(1), PENDING_EVENT(2), PENDING_START(3), PENDING_INTERIM(4), PENDING_CLOSE(5), PENDING_BUFFERED(6); private final int value; ClientRfSessionState(int val) { value = val; } @Override public final int getValue() { return value; } @Override public final ClientRfSessionState fromInt(int val) throws IllegalArgumentException { switch (val) { case 0: return IDLE; case 1: return OPEN; case 2: return PENDING_EVENT; case 3: return PENDING_START; case 4: return PENDING_INTERIM; case 5: return PENDING_CLOSE; case 6: return PENDING_BUFFERED; default: throw new IllegalArgumentException(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rf/IClientRfActionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rf; import org.jdiameter.api.InternalException; import org.jdiameter.api.Request; import org.jdiameter.api.rf.ClientRfSession; /** * Diameter Accounting Client Additional listener Actions for FSM * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IClientRfActionContext { /** * Filling nested avp into interim message * * @param interimRequest instance of interim message which will be sent to server */ void interimIntervalElapses(ClientRfSession appSession, Request interimRequest) throws InternalException; /** * Call back for failed_send_record event * * @param accRequest accounting request record * * @return true if you want put message to buffer and false if you want to stop processing */ boolean failedSendRecord(ClientRfSession appSession, Request accRequest) throws InternalException; /** * Filling nested avp into STR * * @param sessionTermRequest instance of STR which will be sent to server */ void disconnectUserOrDev(ClientRfSession appSession, Request sessionTermRequest) throws InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rf/IRfSessionData.java ================================================ /* * JBoss, Home of Professional Open Source * Copyright 2006, 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.jdiameter.common.api.app.rf; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IRfSessionData extends IAppSessionData { // marker interface } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rf/IRfSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rf; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.rf.ClientRfSessionListener; import org.jdiameter.api.rf.ServerRfSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IRfSessionFactory extends IAppSessionFactory { /** * @return the serverSessionListener */ ServerRfSessionListener getServerSessionListener(); /** * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerRfSessionListener serverSessionListener); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); /** * @return the clientSessionListener */ ClientRfSessionListener getClientSessionListener(); /** * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientRfSessionListener clientSessionListener); /** * @return the clientContextListener */ IClientRfActionContext getClientContextListener(); /** * @param clientContextListener the clientContextListener to set */ void setClientContextListener(IClientRfActionContext clientContextListener); /** * @return the serverContextListener */ IServerRfActionContext getServerContextListener(); /** * @param serverContextListener the serverContextListener to set */ void setServerContextListener(IServerRfActionContext serverContextListener); /** * @return the messageTimeout */ long getMessageTimeout(); /** * @param messageTimeout the messageTimeout to set */ void setMessageTimeout(long messageTimeout); ApplicationId getApplicationId(); void setApplicationId(ApplicationId id); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rf/IServerRfActionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rf; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.InternalException; import org.jdiameter.api.rf.ServerRfSession; /** * Diameter Accounting Server Additional listener Actions for FSM * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerRfActionContext { void sessionTimerStarted(ServerRfSession appSession, ScheduledFuture timer) throws InternalException; void sessionTimeoutElapses(ServerRfSession appSession) throws InternalException; void sessionTimerCanceled(ServerRfSession appSession, ScheduledFuture timer) throws InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rf/ServerRfSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rf; import org.jdiameter.common.api.app.IAppSessionState; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ public enum ServerRfSessionState implements IAppSessionState { IDLE(0), OPEN(1); private final int value; ServerRfSessionState(int val) { value = val; } @Override public final int getValue() { return value; } @Override public final ServerRfSessionState fromInt(int val) throws IllegalArgumentException { switch (val) { case 0: return IDLE; case 1: return OPEN; default: throw new IllegalArgumentException(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/ClientRoSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.ro; import org.jdiameter.common.api.app.IAppSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca * @author Erick Svenson */ public enum ClientRoSessionState implements IAppSessionState { IDLE(0), PENDING_EVENT(1), PENDING_INITIAL(2), PENDING_UPDATE(3), PENDING_TERMINATION(4), PENDING_BUFFERED(5), OPEN(6); private int stateValue; ClientRoSessionState(int stateV) { this.stateValue = stateV; } @Override public ClientRoSessionState fromInt(int v) throws IllegalArgumentException { switch (v) { case 0: return IDLE; case 1: return PENDING_EVENT; case 2: return PENDING_INITIAL; case 3: return PENDING_UPDATE; case 4: return PENDING_TERMINATION; case 5: return PENDING_BUFFERED; case 6: return OPEN; default: throw new IllegalArgumentException("Illegal value of int representation!!!!"); } } @Override public int getValue() { return stateValue; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/IClientRoSessionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.ro; import org.jdiameter.api.Message; import org.jdiameter.api.ro.ClientRoSession; /** * Diameter Ro Application Client Additional listener Actions for FSM * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IClientRoSessionContext { long getDefaultTxTimerValue(); void txTimerExpired(ClientRoSession session); int getDefaultCCFHValue(); int getDefaultDDFHValue(); void grantAccessOnDeliverFailure(ClientRoSession clientCCASessionImpl, Message request); void denyAccessOnDeliverFailure(ClientRoSession clientCCASessionImpl, Message request); void grantAccessOnTxExpire(ClientRoSession clientCCASessionImpl); void denyAccessOnTxExpire(ClientRoSession clientCCASessionImpl); void grantAccessOnFailureMessage(ClientRoSession clientCCASessionImpl); void denyAccessOnFailureMessage(ClientRoSession clientCCASessionImpl); void indicateServiceError(ClientRoSession clientCCASessionImpl); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/IRoMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.ro; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.ro.events.RoCreditControlAnswer; import org.jdiameter.api.ro.events.RoCreditControlRequest; /** * Diameter Ro Application Message Factory * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IRoMessageFactory { ReAuthRequest createReAuthRequest(Request request); ReAuthAnswer createReAuthAnswer(Answer answer); RoCreditControlRequest createCreditControlRequest(Request request); RoCreditControlAnswer createCreditControlAnswer(Answer answer); long[] getApplicationIds(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/IRoSessionData.java ================================================ /* * JBoss, Home of Professional Open Source * Copyright 2008, 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.jdiameter.common.api.app.ro; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IRoSessionData extends IAppSessionData { // marker interface } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/IRoSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.ro; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.ro.ClientRoSessionListener; import org.jdiameter.api.ro.ServerRoSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * Session Factory interface for Diameter Ro Application. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IRoSessionFactory extends IAppSessionFactory { /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the clientSessionListener */ ClientRoSessionListener getClientSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientRoSessionListener clientSessionListener); /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the serverSessionListener */ ServerRoSessionListener getServerSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerRoSessionListener serverSessionListener); /** * @return the serverContextListener */ IServerRoSessionContext getServerContextListener(); /** * @param serverContextListener the serverContextListener to set */ void setServerContextListener(IServerRoSessionContext serverContextListener); /** * @return the clientContextListener */ IClientRoSessionContext getClientContextListener(); /** * @return the messageFactory */ IRoMessageFactory getMessageFactory(); /** * @param messageFactory the messageFactory to set */ void setMessageFactory(IRoMessageFactory messageFactory); /** * @param clientContextListener the clientContextListener to set */ void setClientContextListener(IClientRoSessionContext clientContextListener); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/IServerRoSessionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.ro; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.Request; import org.jdiameter.api.ro.ServerRoSession; /** * Diameter Ro Application Server Additional listener Actions for FSM * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerRoSessionContext { void sessionSupervisionTimerExpired(ServerRoSession session); /** * This is called always when Tcc starts * * @param session * @param future */ void sessionSupervisionTimerStarted(ServerRoSession session, ScheduledFuture future); void sessionSupervisionTimerReStarted(ServerRoSession session, ScheduledFuture future); void sessionSupervisionTimerStopped(ServerRoSession session, ScheduledFuture future); /** * Returns seconds value representing default validity time, App session uses 2x for Tcc timer * * @return */ long getDefaultValidityTime(); void timeoutExpired(Request request); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/ro/ServerRoSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.ro; import org.jdiameter.common.api.app.IAppSessionState; /** * Diameter Ro Application Server states * * @author Bartosz Baranowski * @author Alexandre Mendonca */ public enum ServerRoSessionState implements IAppSessionState { IDLE(0), OPEN(1); private int stateRepresentation; ServerRoSessionState(int v) { this.stateRepresentation = v; } @Override public ServerRoSessionState fromInt(int v) throws IllegalArgumentException { switch (v) { case 0: return IDLE; case 1: return OPEN; default: throw new IllegalArgumentException("Illegal value of int representation!!!!"); } } @Override public int getValue() { return stateRepresentation; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rx/ClientRxSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rx; import org.jdiameter.common.api.app.IAppSessionState; /** * Diameter 3GPP IMS Rx Reference Point Client Session States * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Richard Good */ public enum ClientRxSessionState implements IAppSessionState { IDLE(0), PENDING_AAR(1), PENDING_STR(2), PENDING_EVENT(3), PENDING_BUFFERED(4), OPEN(5); private int stateValue; ClientRxSessionState(int stateV) { this.stateValue = stateV; } @Override public ClientRxSessionState fromInt(int v) throws IllegalArgumentException { switch (v) { case 0: return IDLE; case 1: return PENDING_AAR; case 2: return PENDING_STR; case 3: return PENDING_EVENT; case 4: return PENDING_BUFFERED; case 5: return OPEN; default: throw new IllegalArgumentException("Illegal value of int representation!!!!"); } } @Override public int getValue() { return stateValue; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rx/IClientRxSessionContext.java ================================================ /* * 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.jdiameter.common.api.app.rx; import org.jdiameter.api.Message; import org.jdiameter.api.rx.ClientRxSession; /** * Diameter 3GPP IMS Rx Reference Point Client Additional listener. Actions for FSM * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Richard Good */ @SuppressWarnings("all") //3rd party lib public interface IClientRxSessionContext { void grantAccessOnDeliverFailure(ClientRxSession clientCCASessionImpl, Message request); void denyAccessOnDeliverFailure(ClientRxSession clientCCASessionImpl, Message request); void grantAccessOnFailureMessage(ClientRxSession clientCCASessionImpl); void denyAccessOnFailureMessage(ClientRxSession clientCCASessionImpl); void indicateServiceError(ClientRxSession clientCCASessionImpl); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rx/IRxMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.rx.events.RxAAAnswer; import org.jdiameter.api.rx.events.RxAARequest; import org.jdiameter.api.rx.events.RxAbortSessionAnswer; import org.jdiameter.api.rx.events.RxAbortSessionRequest; import org.jdiameter.api.rx.events.RxReAuthAnswer; import org.jdiameter.api.rx.events.RxReAuthRequest; import org.jdiameter.api.rx.events.RxSessionTermAnswer; import org.jdiameter.api.rx.events.RxSessionTermRequest; /** * Diameter 3GPP IMS Rx Reference Point Message Factory * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Richard Good */ @SuppressWarnings("all") //3rd party lib public interface IRxMessageFactory { RxReAuthRequest createReAuthRequest(Request request); RxReAuthAnswer createReAuthAnswer(Answer answer); RxSessionTermRequest createSessionTermRequest(Request request); RxSessionTermAnswer createSessionTermAnswer(Answer answer); RxAbortSessionRequest createAbortSessionRequest(Request request); RxAbortSessionAnswer createAbortSessionAnswer(Answer answer); RxAARequest createAARequest(Request request); RxAAAnswer createAAAnswer(Answer answer); long[] getApplicationIds(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rx/IRxSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rx; import org.jdiameter.common.api.app.IAppSessionData; /** * Diameter 3GPP IMS Rx Reference Point Session Data * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Richard Good */ @SuppressWarnings("all") //3rd party lib public interface IRxSessionData extends IAppSessionData { // marker interface } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rx/IRxSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rx; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.rx.ClientRxSessionListener; import org.jdiameter.api.rx.ServerRxSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * Session Factory interface for Diameter 3GPP IMS Rx Reference Point. * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Richard Good */ @SuppressWarnings("all") //3rd party lib public interface IRxSessionFactory extends IAppSessionFactory { /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the clientSessionListener */ ClientRxSessionListener getClientSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientRxSessionListener clientSessionListener); /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the serverSessionListener */ ServerRxSessionListener getServerSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerRxSessionListener serverSessionListener); /** * @return the serverContextListener */ IServerRxSessionContext getServerContextListener(); /** * @param serverContextListener the serverContextListener to set */ void setServerContextListener(IServerRxSessionContext serverContextListener); /** * @return the clientContextListener */ IClientRxSessionContext getClientContextListener(); /** * @return the messageFactory */ IRxMessageFactory getMessageFactory(); /** * @param messageFactory the messageFactory to set */ void setMessageFactory(IRxMessageFactory messageFactory); /** * @param clientContextListener the clientContextListener to set */ void setClientContextListener(IClientRxSessionContext clientContextListener); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rx/IServerRxSessionContext.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rx; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.rx.ServerRxSession; /** * Diameter 3GPP IMS Rx Reference Point Server Additional listener Actions for FSM * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Richard Good */ @SuppressWarnings("all") //3rd party lib public interface IServerRxSessionContext { void sessionSupervisionTimerExpired(ServerRxSession session); /** * This is called always when Tcc starts * * @param session * @param future */ void sessionSupervisionTimerStarted(ServerRxSession session, ScheduledFuture future); void sessionSupervisionTimerReStarted(ServerRxSession session, ScheduledFuture future); void sessionSupervisionTimerStopped(ServerRxSession session, ScheduledFuture future); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/rx/ServerRxSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.rx; import org.jdiameter.common.api.app.IAppSessionState; /** * Diameter 3GPP IMS Rx Reference Point Server Session states * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Richard Good */ public enum ServerRxSessionState implements IAppSessionState { IDLE(0), OPEN(1); private int stateRepresentation; ServerRxSessionState(int v) { this.stateRepresentation = v; } @Override public ServerRxSessionState fromInt(int v) throws IllegalArgumentException { switch (v) { case 0: return IDLE; case 1: return OPEN; default: throw new IllegalArgumentException("Illegal value of int representation!!!!"); } } @Override public int getValue() { return stateRepresentation; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/s13/IS13MessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.api.app.s13; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s13.events.JMEIdentityCheckAnswer; import org.jdiameter.api.s13.events.JMEIdentityCheckRequest; @SuppressWarnings("all") //3rd party lib public interface IS13MessageFactory { JMEIdentityCheckRequest createMEIdentityCheckRequest(Request request); JMEIdentityCheckAnswer createMEIdentityCheckAnswer(Answer answer); /** * Returns the Application-Id that this message factory is related to * * @return the Application-Id value */ long getApplicationId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/s13/IS13SessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.api.app.s13; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.IAppSessionData; @SuppressWarnings("all") //3rd party lib public interface IS13SessionData extends IAppSessionData { void setS13SessionState(S13SessionState state); S13SessionState getS13SessionState(); Serializable getTsTimerId(); void setTsTimerId(Serializable tid); void setBuffer(Request buffer); Request getBuffer(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/s13/IS13SessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.api.app.s13; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.s13.ClientS13SessionListener; import org.jdiameter.api.s13.ServerS13SessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; @SuppressWarnings("all") //3rd party lib public interface IS13SessionFactory extends IAppSessionFactory { /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the serverSessionListener */ ServerS13SessionListener getServerSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerS13SessionListener serverSessionListener); /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the clientSessionListener */ ClientS13SessionListener getClientSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientS13SessionListener clientSessionListener); /** * @return the messageFactory */ IS13MessageFactory getMessageFactory(); /** * @param messageFactory the messageFactory to set */ void setMessageFactory(IS13MessageFactory messageFactory); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/s13/S13SessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.api.app.s13; public enum S13SessionState { IDLE, MESSAGE_SENT_RECEIVED, TERMINATED, TIMEDOUT; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/s6a/IS6aMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s6a.events.JAuthenticationInformationAnswer; import org.jdiameter.api.s6a.events.JAuthenticationInformationRequest; import org.jdiameter.api.s6a.events.JCancelLocationAnswer; import org.jdiameter.api.s6a.events.JCancelLocationRequest; import org.jdiameter.api.s6a.events.JDeleteSubscriberDataAnswer; import org.jdiameter.api.s6a.events.JDeleteSubscriberDataRequest; import org.jdiameter.api.s6a.events.JInsertSubscriberDataAnswer; import org.jdiameter.api.s6a.events.JInsertSubscriberDataRequest; import org.jdiameter.api.s6a.events.JNotifyAnswer; import org.jdiameter.api.s6a.events.JNotifyRequest; import org.jdiameter.api.s6a.events.JPurgeUEAnswer; import org.jdiameter.api.s6a.events.JPurgeUERequest; import org.jdiameter.api.s6a.events.JResetAnswer; import org.jdiameter.api.s6a.events.JResetRequest; import org.jdiameter.api.s6a.events.JUpdateLocationAnswer; import org.jdiameter.api.s6a.events.JUpdateLocationRequest; /** * Message Factory for Diameter S6a application. * * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface IS6aMessageFactory { JUpdateLocationRequest createUpdateLocationRequest(Request request); JUpdateLocationAnswer createUpdateLocationAnswer(Answer answer); JCancelLocationRequest createCancelLocationRequest(Request request); JCancelLocationAnswer createCancelLocationAnswer(Answer answer); JAuthenticationInformationRequest createAuthenticationInformationRequest(Request request); JAuthenticationInformationAnswer createAuthenticationInformationAnswer(Answer answer); JInsertSubscriberDataRequest createInsertSubscriberDataRequest(Request request); JInsertSubscriberDataAnswer createInsertSubscriberDataAnswer(Answer answer); JDeleteSubscriberDataRequest createDeleteSubscriberDataRequest(Request request); JDeleteSubscriberDataAnswer createDeleteSubscriberDataAnswer(Answer answer); JPurgeUERequest createPurgeUERequest(Request request); JPurgeUEAnswer createPurgeUEAnswer(Answer answer); JResetRequest createResetRequest(Request request); JResetAnswer createResetAnswer(Answer answer); JNotifyRequest createNotifyRequest(Request request); JNotifyAnswer createNotifyAnswer(Answer answer); /** * Returns the Application-Id that this message factory is related to * * @return the Application-Id value */ long getApplicationId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/s6a/IS6aSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.s6a; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface IS6aSessionData extends IAppSessionData { void setS6aSessionState(S6aSessionState state); S6aSessionState getS6aSessionState(); Serializable getTsTimerId(); void setTsTimerId(Serializable tid); void setBuffer(Request buffer); Request getBuffer(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/s6a/IS6aSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.s6a; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.s6a.ClientS6aSessionListener; import org.jdiameter.api.s6a.ServerS6aSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * Session Factory interface for Diameter S6a application. * * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface IS6aSessionFactory extends IAppSessionFactory { /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the serverSessionListener */ ServerS6aSessionListener getServerSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerS6aSessionListener serverSessionListener); /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the clientSessionListener */ ClientS6aSessionListener getClientSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientS6aSessionListener clientSessionListener); /** * @return the messageFactory */ IS6aMessageFactory getMessageFactory(); /** * @param messageFactory the messageFactory to set */ void setMessageFactory(IS6aMessageFactory messageFactory); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/s6a/S6aSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.s6a; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ public enum S6aSessionState { IDLE, MESSAGE_SENT_RECEIVED, TERMINATED, TIMEDOUT; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/sh/IShMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.sh; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; @SuppressWarnings("all") //3rd party lib public interface IShMessageFactory { AppRequestEvent createProfileUpdateRequest(Request request); AppRequestEvent createPushNotificationRequest(Request request); AppRequestEvent createSubscribeNotificationsRequest(Request request); AppRequestEvent createUserDataRequest(Request request); AppAnswerEvent createProfileUpdateAnswer(Answer answer); AppAnswerEvent createPushNotificationAnswer(Answer answer); AppAnswerEvent createSubscribeNotificationsAnswer(Answer answer); AppAnswerEvent createUserDataAnswer(Answer answer); long getApplicationId(); long getMessageTimeout(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/sh/IShSessionData.java ================================================ /* * JBoss, Home of Professional Open Source * Copyright 2008, 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.jdiameter.common.api.app.sh; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IShSessionData extends IAppSessionData { // marker interface } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/sh/IShSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.sh; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.sh.ClientShSessionListener; import org.jdiameter.api.sh.ServerShSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; /** * Diameter Sh Session Factory * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IShSessionFactory extends IAppSessionFactory { void setClientShSessionListener(ClientShSessionListener v); ClientShSessionListener getClientShSessionListener(); void setServerShSessionListener(ServerShSessionListener v); ServerShSessionListener getServerShSessionListener(); void setStateChangeListener(StateChangeListener v); StateChangeListener getStateChangeListener(); void setMessageFactory(IShMessageFactory factory); IShMessageFactory getMessageFactory(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgMessageFactory.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.api.app.slg; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.slg.events.LocationReportAnswer; import org.jdiameter.api.slg.events.LocationReportRequest; import org.jdiameter.api.slg.events.ProvideLocationAnswer; import org.jdiameter.api.slg.events.ProvideLocationRequest; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ISLgMessageFactory { ProvideLocationRequest createProvideLocationRequest(Request request); ProvideLocationAnswer createProvideLocationAnswer(Answer answer); LocationReportRequest createLocationReportRequest(Request request); LocationReportAnswer createLocationReportAnswer(Answer answer); /** * Returns the Application-Id that this message factory is related to * * @return the Application-Id value */ long getApplicationId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgSessionData.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.api.app.slg; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ISLgSessionData extends IAppSessionData { void setSLgSessionState(SLgSessionState state); SLgSessionState getSLgSessionState(); Serializable getTsTimerId(); void setTsTimerId(Serializable tid); void setBuffer(Request buffer); Request getBuffer(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgSessionFactory.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.api.app.slg; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.slg.ClientSLgSessionListener; import org.jdiameter.api.slg.ServerSLgSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; // import org.jdiameter.common.api.app.slg.ISLgMessageFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ISLgSessionFactory extends IAppSessionFactory { /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the serverSessionListener */ ServerSLgSessionListener getServerSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerSLgSessionListener serverSessionListener); /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the clientSessionListener */ ClientSLgSessionListener getClientSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientSLgSessionListener clientSessionListener); /** * @return the messageFactory */ ISLgMessageFactory getMessageFactory(); /** * @param messageFactory the messageFactory to set */ void setMessageFactory(ISLgMessageFactory messageFactory); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/SLgSessionState.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.api.app.slg; /** * @author Fernando Mendioroz */ public enum SLgSessionState { IDLE, MESSAGE_SENT_RECEIVED, TERMINATED, TIMEDOUT; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhMessageFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.slh; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ISLhMessageFactory { LCSRoutingInfoRequest createLCSRoutingInfoRequest(Request request); LCSRoutingInfoAnswer createLCSRoutingInfoAnswer(Answer answer); /** * Returns the Application-Id that this message factory is related to * * @return the Application-Id value */ long getApplicationId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.slh; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.IAppSessionData; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ISLhSessionData extends IAppSessionData { void setSLhSessionState(SLhSessionState state); SLhSessionState getSLhSessionState(); Serializable getTsTimerId(); void setTsTimerId(Serializable tid); void setBuffer(Request buffer); Request getBuffer(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhSessionFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.slh; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.slh.ClientSLhSessionListener; import org.jdiameter.api.slh.ServerSLhSessionListener; import org.jdiameter.common.api.app.IAppSessionFactory; // import org.jdiameter.common.api.app.slh.ISLhMessageFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface ISLhSessionFactory extends IAppSessionFactory { /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the serverSessionListener */ ServerSLhSessionListener getServerSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param serverSessionListener the serverSessionListener to set */ void setServerSessionListener(ServerSLhSessionListener serverSessionListener); /** * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @return the clientSessionListener */ ClientSLhSessionListener getClientSessionListener(); /** * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app * session. However clustered session use this value when recreated! * * @param clientSessionListener the clientSessionListener to set */ void setClientSessionListener(ClientSLhSessionListener clientSessionListener); /** * @return the messageFactory */ ISLhMessageFactory getMessageFactory(); /** * @param messageFactory the messageFactory to set */ void setMessageFactory(ISLhMessageFactory messageFactory); /** * @return the stateListener */ StateChangeListener getStateListener(); /** * @param stateListener the stateListener to set */ void setStateListener(StateChangeListener stateListener); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/SLhSessionState.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.app.slh; /** * @author Fernando Mendioroz */ public enum SLhSessionState { IDLE, MESSAGE_SENT_RECEIVED, TERMINATED, TIMEDOUT; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/concurrent/DummyConcurrentFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.concurrent; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; import org.jdiameter.common.api.statistic.IStatistic; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class DummyConcurrentFactory implements IConcurrentFactory { @Override public ThreadPoolExecutor getThreadPool() { return null; } @Override public ScheduledExecutorService getScheduledExecutorService(String name) { return Executors.newScheduledThreadPool(4); } @Override public Collection getScheduledExecutorServices() { return new ArrayList(); } @Override public void shutdownNow(ScheduledExecutorService service) { } @Override public IStatistic getStatistic() { return null; } @Override public List getStatistics() { // TODO Auto-generated method stub return new ArrayList(); } @Override public void shutdownAllNow() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/concurrent/IConcurrentEntityFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticRecord; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IConcurrentEntityFactory { ThreadFactory newThreadFactory(); RejectedExecutionHandler newRejectedExecutionHandler(IStatisticRecord rejectedCount); //TODO: get rid of those. Callable newDefaultCallable(Callable runnable, IStatistic statistic, IStatisticRecord... statisticRecords); Runnable newDefaultRunnable(Runnable runnable, IStatistic statistic, IStatisticRecord... statisticRecords); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/concurrent/IConcurrentFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.concurrent; import java.util.Collection; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import org.jdiameter.common.api.statistic.IStatistic; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IConcurrentFactory { enum ScheduledExecServices { ProcessingMessageTimer, RedirectMessageTimer, DuplicationMessageTimer, PeerOverloadTimer, ConnectionTimer, StatisticTimer, ApplicationSession } ExecutorService getThreadPool(); // ScheduledExecutorService ScheduledExecutorService getScheduledExecutorService(String name); Collection getScheduledExecutorServices(); void shutdownNow(ScheduledExecutorService service); // Common IStatistic getStatistic(); List getStatistics(); void shutdownAllNow(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/data/ISessionDatasource.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.data; import org.jdiameter.api.BaseSession; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.common.api.app.IAppSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ISessionDatasource { void start(); void stop(); boolean exists(String sessionId); NetworkReqListener getSessionListener(String sessionId); void setSessionListener(String sessionId, NetworkReqListener data); NetworkReqListener removeSessionListener(String sessionId); void removeSession(String sessionId); void addSession(BaseSession session); BaseSession getSession(String sessionId); boolean isClustered(); IAppSessionDataFactory getDataFactory(Class x); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/statistic/IStatistic.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.statistic; import org.jdiameter.api.Statistic; /** * This interface describe extends methods of base class * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IStatistic extends Statistic { enum Groups { Peer("Peer statistic"), PeerFSM("Peer FSM statistic"), Network("Network statistic"), Concurrent(" Concurrent factory statistics"), ScheduledExecService("ScheduledExecutorService statistic"); private String description; Groups(String description) { this.description = description; } public String getDescription() { return description; } } /** * Merge statistic * * @param rec external statistic */ void appendCounter(IStatisticRecord... rec); IStatisticRecord getRecordByName(String name); IStatisticRecord getRecordByName(IStatisticRecord.Counters name); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/statistic/IStatisticManager.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.statistic; import java.util.List; import java.util.Set; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IStatisticManager { IStatisticRecord newCounterRecord(IStatisticRecord.Counters recordDescription); IStatisticRecord newCounterRecord(IStatisticRecord.Counters recordDescription, IStatisticRecord.ValueHolder counters); IStatisticRecord newCounterRecord(IStatisticRecord.Counters recordDescription, IStatisticRecord.ValueHolder counters, IStatisticRecord... rec); IStatisticRecord newCounterRecord(String name, String description); IStatisticRecord newCounterRecord(String name, String description, IStatisticRecord.ValueHolder counter); IStatisticRecord newPerSecondCounterRecord(String name, IStatisticRecord.Counters recordDescription, IStatisticRecord record); IStatistic newStatistic(String name, IStatistic.Groups group, IStatisticRecord... rec); //IStatistic newStatistic(String name, String description, IStatisticRecord... rec); //void removePerSecondCounterRecord(String name, IStatisticRecord.Counters recordDescription); void removePerSecondCounterRecord(IStatisticRecord rec); //void removeStatistic(String name); //void removeStatistic(String name, IStatistic.Groups group); void removeStatistic(IStatistic stat); // --- non factory methods, metadata access boolean isOn(); long getPause(); long getDelay(); Set getEnabled(); // --- access method List getPSStatisticRecord(); List getStatistic(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/statistic/IStatisticProcessor.java ================================================ package org.jdiameter.common.api.statistic; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IStatisticProcessor { void start(); void stop(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/statistic/IStatisticRecord.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.statistic; import org.jdiameter.api.StatisticRecord; /** * This interface describe extends methods of base class * * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IStatisticRecord extends StatisticRecord { enum Counters { AppGenRequest("Count of app generated requests"), AppGenRejectedRequest("Count of rejected app generated requests"), AppGenResponse("Count of app generated responses"), AppGenRejectedResponse("Count of rejected app generated responses"), NetGenRequest("Count of network generated processed requests"), NetGenRejectedRequest("Count of network generated rejected requests"), NetGenResponse("Count of network generated processed responses"), NetGenRejectedResponse("Count of network generated rejected responses"), SysGenResponse("Count of platform generated responses"), AppGenRequestPerSecond("Count of app generated request per second"), AppGenResponsePerSecond("Count of app generated responses per second"), NetGenResponsePerSecond("Count of network generated responses per second"), NetGenRequestPerSecond("Count of network generated request per second"), RequestListenerCount("Count of network request appIdToNetListener"), SelectorCount("Count of network request selectorToNetListener"), HeapMemory("Heap memory usage"), NoHeapMemory("No-heap memory usage"), MessageProcessingTime("Average time of processing message"), ConcurrentThread("Count thread in default thread group"), ConcurrentScheduledExecutedServices("Count of ScheduledExecutorServices"), WorkingThread("Count of working thread"), CanceledTasks("Count of canceled thread"), ExecTimeTask("Average execution time of task"), WaitTimeTask("Average waiting time for execution task"), BrokenTasks("Count of broken thread"), RejectedTasks("Count of rejected tasks"), QueueSize("Peer FSM queue size"); private String description; Counters(String description) { this.description = description; } public String getDescription() { return description; } } /** * Increment counter */ void inc(); /** * Increment counter */ void inc(long value); /** * Decrement counter */ void dec(); /** * Set value of statistic * * @param value new value of record */ void setLongValue(long value); /** * Set value of statistic * * @param value new value of record */ void setDoubleValue(double value); /** * ValueHolder for external statistics */ @SuppressWarnings("all") //3rd party lib public interface ValueHolder { String getValueAsString(); } @SuppressWarnings("all") //3rd party lib public interface IntegerValueHolder extends ValueHolder { /** * Return value of counter as integer * * @return value of counter */ int getValueAsInt(); } @SuppressWarnings("all") //3rd party lib public interface LongValueHolder extends ValueHolder { /** * Return value of counter as long * * @return value of counter */ long getValueAsLong(); } @SuppressWarnings("all") //3rd party lib public interface DoubleValueHolder extends ValueHolder { /** * Return value of counter as double * * @return value of counter */ double getValueAsDouble(); } //=========================== } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/api/timer/ITimerFacility.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.api.timer; import java.io.Serializable; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ITimerFacility { Serializable schedule(String sessionId, String timerName, long miliseconds) throws IllegalArgumentException; void cancel(Serializable id); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/DiameterUtilities.java ================================================ /* * Copyright (C) 2018 TradeSwitch (Pty) Ltd * All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of MobileData (Pty) Ltd and its suppliers, * if any. The intellectual and technical concepts contained * herein are proprietary to MobileData (Pty) Ltd * and its suppliers and may be covered by South African and Foreign Patents, * patents in process, and are protected by trade secret or copyright law. * * Dissemination of this information or reproduction of this material * is strictly forbidden unless prior written permission is obtained * from TradeSwitch (Pty) Ltd. * * */ package org.jdiameter.common.impl; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Message; import org.jdiameter.api.validation.AvpRepresentation; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.common.impl.validation.AvpRepresentationImpl; import org.jdiameter.common.impl.validation.DictionaryImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DiameterUtilities { private static final Logger LOG = LoggerFactory.getLogger(DiameterUtilities.class); public static final Dictionary AVP_DICTIONARY = DictionaryImpl.INSTANCE; private DiameterUtilities() { } public static void printMessage(Message message) { if (LOG.isTraceEnabled()) { String reqFlag = message.isRequest() ? "R" : "A"; String flags = reqFlag + (message.isError() ? " | E" : ""); LOG.trace("Message [{}] Command-Code: {} / E2E({}) / HbH({})", flags, message.getCommandCode(), message.getEndToEndIdentifier(), message.getHopByHopIdentifier()); LOG.trace("\n- - - - - - - - - - - - - - - - AVPs - - - - - - - - - - - - - - - -\n{}", printAvps(message.getAvps())); } //if }//printMessage public static void printMessage(String logHeading, AvpSet avps) { if (LOG.isTraceEnabled()) { LOG.trace("{}\n- - - - - - - - - - - - - - - - AVPs - - - - - - - - - - - - - - - -\n{}", logHeading, printAvps(avps)); } //if }//printMessage public static String printAvps(AvpSet avps, String keywordSep) { return printAvps(avps, keywordSep, "", false); } public static String printAvps(AvpSet avps) { return printAvps(avps, "-"); }//printAvps public static String printAvps(AvpSet avps, String indentation, boolean log) { return printAvps(avps, "-", indentation, log); } public static String printAvps(AvpSet avps, String pKeywordSep, String indentation, boolean log) { if (avps == null) { return "AvpSet is null"; } //if StringBuilder stringBuilder = new StringBuilder(); for (Avp avp : avps) { AvpRepresentation avpRep = AVP_DICTIONARY.getAvp(avp.getCode(), avp.getVendorId()); if (avpRep == null) { avpRep = new AvpRepresentationImpl("Unknown AVP " + avp.getCode(), "Unknown AVP", avp.getCode(), false, null, null, null, avp.getVendorId(), AvpRepresentation.Type.UTF8String.toString(), AvpRepresentation.Type.UTF8String.toString()); } Object avpValue; boolean isGrouped = false; try { String avpType = avpRep.getType(); if (null == avpType) { avpValue = avp.getUTF8String().replace("\r", "").replace("\n", ""); } //if else { switch (avpType) { case "Integer32", "AppId": avpValue = avp.getInteger32(); break; case "Unsigned32", "VendorId": avpValue = avp.getUnsigned32(); break; case "Float64": avpValue = avp.getFloat64(); break; case "Integer64": avpValue = avp.getInteger64(); break; case "Time": avpValue = avp.getTime(); break; case "Unsigned64": avpValue = avp.getUnsigned64(); break; case "Grouped": avpValue = ""; isGrouped = true; break; default: avpValue = avp.getUTF8String().replace("\r", "").replace("\n", ""); break; }//else Switch } } //try catch (AvpDataException ignore) { try { avpValue = avp.getUTF8String().replace("\r", "").replace("\n", ""); } //try catch (AvpDataException e) { avpValue = avp.toString(); } //catch } //catch String fieldName = avpRep.getName().replace("-", pKeywordSep); StringBuilder avpLine = new StringBuilder(indentation) .append(avp.getCode()) .append(": ") .append(fieldName); while (avpLine.length() < 40) { avpLine.append(avpLine.length() % 2 == 0 ? "." : " "); } //while avpLine.append(avpValue); if (log && LOG.isDebugEnabled()) { LOG.debug(avpLine.toString()); } //if stringBuilder.append(avpLine).append('\n'); if (isGrouped) { try { stringBuilder.append(printAvps(avp.getGrouped(), pKeywordSep, indentation + " ", log)); } //try catch (AvpDataException e) { // Failed to ungroup... ignore then... } //catch } //if } //for return stringBuilder.toString(); }//printAvps }//DiameterUtilities ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppAnswerEventImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppAnswerEvent; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AppAnswerEventImpl extends AppEventImpl implements AppAnswerEvent { private static final long serialVersionUID = 1L; public AppAnswerEventImpl(Request request, long resultCode) { this(request.createAnswer(resultCode)); } public AppAnswerEventImpl(Request request, long vendorId, long resultCode) { this(request.createAnswer(vendorId, resultCode)); } public AppAnswerEventImpl(Request request) { this(request.createAnswer()); } public AppAnswerEventImpl(Answer answer) { super(answer); } @Override public Avp getResultCodeAvp() throws AvpDataException { Avp resultCodeAvp = message.getAvps().getAvp(Avp.RESULT_CODE); if (resultCodeAvp != null) { return resultCodeAvp; } resultCodeAvp = message.getAvps().getAvp(Avp.EXPERIMENTAL_RESULT); if (resultCodeAvp != null) { return resultCodeAvp.getGrouped().getAvp(Avp.EXPERIMENTAL_RESULT_CODE); } return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppEventImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app; import static org.jdiameter.api.Avp.ORIGIN_HOST; import static org.jdiameter.api.Avp.ORIGIN_REALM; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.app.AppEvent; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class AppEventImpl implements AppEvent { private static final long serialVersionUID = 1L; protected Message message; public AppEventImpl(Message message) { this.message = message; } @Override public int getCommandCode() { return message.getCommandCode(); } @Override public Message getMessage() throws InternalException { return message; } @Override public String getOriginHost() throws AvpDataException { Avp originHostAvp = message.getAvps().getAvp(ORIGIN_HOST); if (originHostAvp != null) { return originHostAvp.getDiameterIdentity(); } else { throw new AvpDataException("Avp ORIGIN_HOST not found"); } } @Override public String getOriginRealm() throws AvpDataException { Avp originRealmAvp = message.getAvps().getAvp(ORIGIN_REALM); if (originRealmAvp != null) { return originRealmAvp.getDiameterIdentity(); } else { throw new AvpDataException("Avp ORIGIN_REALM not found"); } } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } AppEventImpl that = (AppEventImpl) o; return message.equals(that.message); } @Override public int hashCode() { return message.hashCode(); } @Override public String toString() { return message != null ? message.toString() : "empty"; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppRequestEventImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app; import static org.jdiameter.api.Avp.DESTINATION_HOST; import static org.jdiameter.api.Avp.DESTINATION_REALM; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Message; import org.jdiameter.api.app.AppRequestEvent; /** * @author erick.svenson@yahoo.com * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class AppRequestEventImpl extends AppEventImpl implements AppRequestEvent { private static final long serialVersionUID = 1L; public AppRequestEventImpl(Message message) { super(message); } @Override public String getDestinationHost() throws AvpDataException { Avp destHostAvp = message.getAvps().getAvp(DESTINATION_HOST); if (destHostAvp != null) { return destHostAvp.getDiameterIdentity(); } else { throw new AvpDataException("Avp DESTINATION_HOST not found"); } } @Override public String getDestinationRealm() throws AvpDataException { Avp destRealmAvp = message.getAvps().getAvp(DESTINATION_REALM); if (destRealmAvp != null) { return destRealmAvp.getDiameterIdentity(); } else { throw new AvpDataException("Avp DESTINATION_REALM not found"); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/AppSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app; import static org.jdiameter.client.impl.helpers.Parameters.SessionTimeOut; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ScheduledExecutorService; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Session; import org.jdiameter.api.app.AppSession; import org.jdiameter.client.api.IAssembler; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionData; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.timer.ITimerFacility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Abstract implementation for {@link AppSession} * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public abstract class AppSessionImpl implements AppSession { private static final Logger logger = LoggerFactory.getLogger(AppSessionImpl.class); protected IAppSessionData appSessionData; protected List sessions; protected Session session; protected ISessionFactory sf = null; protected ScheduledExecutorService scheduler = null; protected ITimerFacility timerFacility; protected long maxIdleTime = 0; public AppSessionImpl(ISessionFactory sf, IAppSessionData appSessionData) { if (sf == null) { throw new IllegalArgumentException("SessionFactory must not be null"); } if (appSessionData == null) { throw new IllegalArgumentException("IAppSessionData must not be null"); } try { this.sf = sf; this.appSessionData = appSessionData; IAssembler assembler = (this.sf).getContainer().getAssemblerFacility(); this.scheduler = assembler.getComponentInstance(IConcurrentFactory.class) .getScheduledExecutorService(IConcurrentFactory.ScheduledExecServices.ApplicationSession.name()); this.timerFacility = assembler.getComponentInstance(ITimerFacility.class); this.maxIdleTime = this.sf.getContainer().getConfiguration().getLongValue(SessionTimeOut.ordinal(), (Long) SessionTimeOut.defValue()); this.session = this.sf.getNewSession(this.appSessionData.getSessionId()); //annoying ;[ ArrayList list = new ArrayList(); list.add(this.session); this.sessions = Collections.unmodifiableList(list); } catch (Exception e) { throw new IllegalArgumentException(e); } } @Override public long getCreationTime() { return session.getCreationTime(); } @Override public long getLastAccessedTime() { return session.getLastAccessedTime(); } @Override public boolean isValid() { return session == null ? false : session.isValid(); } @Override public ApplicationId getSessionAppId() { return this.appSessionData.getApplicationId(); } @Override public List getSessions() { return this.sessions; //.... } @Override public void release() { logger.debug("Releasing application session for Session ID '{}' ({}).", getSessionId(), getSessionAppId()); this.session.setRequestListener(null); this.session.release(); this.appSessionData.remove(); } /* * (non-Javadoc) * * @see org.jdiameter.api.BaseSession#getSessionId() */ @Override public String getSessionId() { //use local object, its faster :) return this.session.getSessionId(); } /* * (non-Javadoc) * * @see org.jdiameter.api.BaseSession#isAppSession() */ @Override public boolean isAppSession() { return true; } /* * (non-Javadoc) * * @see org.jdiameter.api.BaseSession#isReplicable() */ @Override public boolean isReplicable() { // FIXME: make this true? return false; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((appSessionData == null) ? 0 : appSessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } AppSessionImpl other = (AppSessionImpl) obj; if (appSessionData == null) { if (other.appSessionData != null) { return false; } } else if (!appSessionData.equals(other.appSessionData)) { return false; } return true; } public abstract void onTimer(String timerName); protected void checkIdleAppSession() { if (!isValid() || (maxIdleTime > 0 && System.currentTimeMillis() - getLastAccessedTime() >= maxIdleTime)) { logger.debug("Terminating idle/invalid application session [{}] with SID[{}]", this, getSessionId()); release(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/acc/AccLocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.acc; import org.jdiameter.api.acc.ClientAccSession; import org.jdiameter.api.acc.ServerAccSession; import org.jdiameter.api.app.AppSession; import org.jdiameter.client.impl.app.acc.ClientAccSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.acc.IAccSessionData; import org.jdiameter.server.impl.app.acc.ServerAccSessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class AccLocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IAccSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientAccSession.class)) { ClientAccSessionDataLocalImpl data = new ClientAccSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerAccSession.class)) { ServerAccSessionDataLocalImpl data = new ServerAccSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } throw new IllegalArgumentException(clazz.toString()); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/acc/AccSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.acc; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.acc.ClientAccSession; import org.jdiameter.api.acc.ClientAccSessionListener; import org.jdiameter.api.acc.ServerAccSession; import org.jdiameter.api.acc.ServerAccSessionListener; import org.jdiameter.api.acc.events.AccountAnswer; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.acc.ClientAccSessionImpl; import org.jdiameter.client.impl.app.acc.IClientAccSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.acc.IAccMessageFactory; import org.jdiameter.common.api.app.acc.IAccSessionData; import org.jdiameter.common.api.app.acc.IAccSessionFactory; import org.jdiameter.common.api.app.acc.IClientAccActionContext; import org.jdiameter.common.api.app.acc.IServerAccActionContext; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.acc.IServerAccSessionData; import org.jdiameter.server.impl.app.acc.ServerAccSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default Diameter Account Session Factory implementation * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class AccSessionFactoryImpl implements IAccSessionFactory, IAccMessageFactory, ServerAccSessionListener, ClientAccSessionListener, IClientAccActionContext, IServerAccActionContext, StateChangeListener { protected static final Logger logger = LoggerFactory.getLogger(AccSessionFactoryImpl.class); protected ServerAccSessionListener serverSessionListener; protected StateChangeListener stateListener; protected ClientAccSessionListener clientSessionListener; protected IClientAccActionContext clientContextListener; protected IServerAccActionContext serverContextListener; protected ISessionDatasource iss; protected ISessionFactory sessionFactory = null; protected ApplicationId applicationId; protected IAccMessageFactory messageFactory = this; protected IAppSessionDataFactory sessionDataFactory; protected AccSessionFactoryImpl() { } public AccSessionFactoryImpl(SessionFactory sessionFactory) { super(); setSessionFactory((ISessionFactory) sessionFactory); } // ACC Factory Methods ------------------------------------------------------ /** * @return the serverSessionListener */ @Override public ServerAccSessionListener getServerSessionListener() { if (this.serverSessionListener != null) { return serverSessionListener; } else { return this; } } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerAccSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { if (this.stateListener != null) { return stateListener; } else { return this; } } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } /** * @return the clientSessionListener */ @Override public ClientAccSessionListener getClientSessionListener() { if (this.clientSessionListener != null) { return clientSessionListener; } else { return this; } } /** * @param clientSessionListener the clientSessionListener to set */ @Override public void setClientSessionListener(ClientAccSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the clientContextListener */ @Override public IClientAccActionContext getClientContextListener() { if (this.clientContextListener != null) { return clientContextListener; } else { return this; } } /** * @param clientContextListener the clientContextListener to set */ @Override public void setClientContextListener(IClientAccActionContext clientContextListener) { this.clientContextListener = clientContextListener; } /** * @return the serverContextListener */ @Override public IServerAccActionContext getServerContextListener() { if (this.serverContextListener != null) { return serverContextListener; } else { return this; } } /** * @param serverContextListener the serverContextListener to set */ @Override public void setServerContextListener(IServerAccActionContext serverContextListener) { this.serverContextListener = serverContextListener; } @Override public void setMessageFactory(IAccMessageFactory messageFactory) { this.messageFactory = messageFactory; } @Override public IAccMessageFactory getMessageFactory() { return this.messageFactory; } /** * @return the sessionFactory */ public ISessionFactory getSessionFactory() { return sessionFactory; } /** * @param sessionFactory the sessionFactory to set */ public void setSessionFactory(ISessionFactory sessionFactory) { this.sessionFactory = sessionFactory; if (this.iss == null) { this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IAccSessionData.class); if (this.sessionDataFactory == null) { logger.debug("No factory for Accounting Application data, using default/local."); this.sessionDataFactory = new AccLocalSessionDataFactory(); } } } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IAccSessionFactory#getApplicationId() */ @Override public ApplicationId getApplicationId() { return this.applicationId; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IAccSessionFactory#setApplicationId( org.jdiameter.api.ApplicationId) */ @Override public void setApplicationId(ApplicationId id) { this.applicationId = id; } // App Session Factory ------------------------------------------------------ @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ClientAccSession.class) { IClientAccSessionData data = (IClientAccSessionData) this.sessionDataFactory .getAppSessionData(ClientAccSession.class, sessionId); ClientAccSessionImpl clientSession = new ClientAccSessionImpl(data, sessionFactory, getClientSessionListener(), getClientContextListener(), getStateListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerAccSession.class) { ServerAccSessionImpl serverSession = null; IServerAccSessionData data = (IServerAccSessionData) this.sessionDataFactory .getAppSessionData(ServerAccSession.class, sessionId); //here we use shorter con, since some data is already present. serverSession = new ServerAccSessionImpl(data, sessionFactory, getServerSessionListener(), getServerContextListener(), getStateListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientAccSession.class + "," + ServerAccSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Accounting Session.", e); } return appSession; } @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { try { if (aClass == ServerAccSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } boolean stateless = true; if (args != null && args.length > 0) { for (Object o : args) { if (o instanceof Boolean) { stateless = (Boolean) o; } } } IServerAccSessionData data = (IServerAccSessionData) this.sessionDataFactory .getAppSessionData(ServerAccSession.class, sessionId); data.setApplicationId(applicationId); ServerAccSessionImpl session = new ServerAccSessionImpl(data, sessionFactory, getServerSessionListener(), getServerContextListener(), getStateListener(), stateless); iss.addSession(session); session.getSessions().get(0).setRequestListener(session); return session; } else if (aClass == ClientAccSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientAccSessionData data = (IClientAccSessionData) this.sessionDataFactory .getAppSessionData(ClientAccSession.class, sessionId); data.setApplicationId(applicationId); ClientAccSessionImpl session = new ClientAccSessionImpl(data, sessionFactory, getClientSessionListener(), getClientContextListener(), getStateListener()); iss.addSession(session); session.getSessions().get(0).setRequestListener(session); return session; } } catch (Exception e) { logger.error("Failure to obtain new Accounting Session.", e); } return null; } // State Change Listener ---------------------------------------------------- @Override public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter ACC SessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter ACC SessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } // /////////////////// // Event listeners // // /////////////////// @Override public void doAccRequestEvent(ServerAccSession appSession, AccountRequest acr) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AccountingSessionFactory :: doAccRequestEvent :: appSession[" + appSession + "], Request[" + acr + "]"); } @Override public void doAccAnswerEvent(ClientAccSession appSession, AccountRequest acr, AccountAnswer aca) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("doAccAnswerEvent :: appSession[" + appSession + "], Request[" + acr + "], Answer[" + aca + "]"); } @Override public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AccountingSessionFactory :: doOtherEvent :: appSession[" + appSession + "], Request[" + request + "], Answer[" + answer + "]"); } // Client context ----------------------------------------------------------- /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IClientAccActionContext#disconnectUserOrDev (org.jdiameter.api.Request) */ @Override public void disconnectUserOrDev(ClientAccSession appSession, Request sessionTermRequest) throws InternalException { logger.info("disconnectUserOrDev :: appSession[" + appSession + "], Request[" + sessionTermRequest + "]"); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IClientAccActionContext#failedSendRecord (org.jdiameter.api.Request) */ @Override public boolean failedSendRecord(ClientAccSession appSession, Request accRequest) throws InternalException { logger.info("failedSendRecord :: appSession[" + appSession + "], Request[" + accRequest + "]"); return false; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IClientAccActionContext# interimIntervalElapses(org.jdiameter.api.Request) */ @Override public void interimIntervalElapses(ClientAccSession appSession, Request interimRequest) throws InternalException { logger.info("interimIntervalElapses :: appSession[" + appSession + "], Request[" + interimRequest + "]"); } // Server context ----------------------------------------------------------- /* * (non-Javadoc) * * @seeorg.jdiameter.common.api.app.acc.IServerAccActionContext#sessionTimeoutElapses(org.jdiameter.api.acc. * ServerAccSession) */ @Override public void sessionTimeoutElapses(ServerAccSession appSession) throws InternalException { logger.info("sessionTimeoutElapses :: appSession[" + appSession + "]"); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IServerAccActionContext# * sessionTimerStarted(org.jdiameter.api.acc.ServerAccSession, java.util.concurrent.ScheduledFuture) */ @Override @SuppressWarnings("unchecked") public void sessionTimerStarted(ServerAccSession appSession, ScheduledFuture timer) throws InternalException { logger.info("sessionTimerStarted :: appSession[" + appSession + "]"); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IServerAccActionContext# * sessionTimerCanceled(org.jdiameter.api.acc.ServerAccSession, java.util.concurrent.ScheduledFuture) */ @Override @SuppressWarnings("unchecked") public void sessionTimerCanceled(ServerAccSession appSession, ScheduledFuture timer) throws InternalException { logger.info("sessionTimerCanceled :: appSession[" + appSession + "]"); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IAccMessageFactory#getAccMessageCommandCode() */ @Override public int getAccMessageCommandCode() { // TODO Auto-generated method stub return AccountRequest.code; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IAccMessageFactory#createAccRequest(org.jdiameter.api.Request) */ @Override public AccountRequest createAccRequest(Request request) { return new AccountRequestImpl(request); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IAccMessageFactory#createAccAnswer(org.jdiameter.api.Answer) */ @Override public AccountAnswer createAccAnswer(Answer answer) { return new AccountAnswerImpl(answer); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/acc/AccountAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.acc; import static org.jdiameter.api.Avp.ACC_RECORD_NUMBER; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.acc.events.AccountAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * erick.svenson@yahoo.com * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AccountAnswerImpl extends AppAnswerEventImpl implements AccountAnswer { private static final long serialVersionUID = 1L; public AccountAnswerImpl(Request request, int accountRecordType, int accReqNumber, long resultCode) { this(request.createAnswer(resultCode)); try { getMessage().getAvps().addAvp(Avp.ACC_RECORD_TYPE, accountRecordType); getMessage().getAvps().addAvp(Avp.ACC_RECORD_NUMBER, accReqNumber); } catch (Exception e) { throw new IllegalArgumentException(e); } } /** * @param answer */ public AccountAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public AccountAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public AccountAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public AccountAnswerImpl(Request request) { super(request); } @Override public int getAccountingRecordType() throws AvpDataException { Avp accRecordTypeAvp = message.getAvps().getAvp(Avp.ACC_RECORD_TYPE); if (accRecordTypeAvp != null) { return accRecordTypeAvp.getInteger32(); } else { throw new AvpDataException("Avp ACC_RECORD_TYPE not found"); } } @Override public long getAccountingRecordNumber() throws AvpDataException { Avp accRecordNumberAvp = message.getAvps().getAvp(ACC_RECORD_NUMBER); if (accRecordNumberAvp != null) { return accRecordNumberAvp.getUnsigned32(); } else { throw new AvpDataException("Avp ACC_RECORD_NUMBER not found"); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/acc/AccountRequestImpl.java ================================================ /* /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.acc; import static org.jdiameter.api.Avp.ACC_RECORD_NUMBER; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.AppSession; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AccountRequestImpl extends AppRequestEventImpl implements AccountRequest { private static final long serialVersionUID = 1L; public AccountRequestImpl(AppSession session, int accountRecordType, int accReqNumber, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); try { getMessage().getAvps().addAvp(Avp.ACC_RECORD_TYPE, accountRecordType); getMessage().getAvps().addAvp(Avp.ACC_RECORD_NUMBER, accReqNumber); } catch (Exception e) { throw new IllegalArgumentException(e); } } public AccountRequestImpl(Request request) { super(request); } @Override public int getAccountingRecordType() throws AvpDataException { Avp accRecordTypeAvp = message.getAvps().getAvp(Avp.ACC_RECORD_TYPE); if (accRecordTypeAvp != null) { return accRecordTypeAvp.getInteger32(); } else { throw new AvpDataException("Avp ACC_RECORD_TYPE not found"); } } @Override public long getAccountingRecordNumber() throws AvpDataException { Avp accRecordNumberAvp = message.getAvps().getAvp(ACC_RECORD_NUMBER); if (accRecordNumberAvp != null) { return accRecordNumberAvp.getUnsigned32(); } else { throw new AvpDataException("Avp ACC_RECORD_NUMBER not found"); } } @Override public void setAccountingRecordType(int recordType) throws AvpDataException { message.getAvps().removeAvp(Avp.ACC_RECORD_TYPE); message.getAvps().addAvp(Avp.ACC_RECORD_TYPE, recordType); } @Override public void setAccountingRecordNumber(long recordNum) throws AvpDataException { message.getAvps().removeAvp(Avp.ACC_RECORD_NUMBER); message.getAvps().addAvp(Avp.ACC_RECORD_NUMBER, ACC_RECORD_NUMBER, true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/acc/AppAccSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.acc; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.Answer; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.Request; import org.jdiameter.api.acc.events.AccountAnswer; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public abstract class AppAccSessionImpl extends AppSessionImpl implements NetworkReqListener, org.jdiameter.api.app.StateMachine { protected Lock sendAndStateLock = new ReentrantLock(); protected transient List stateListeners = new CopyOnWriteArrayList(); public AppAccSessionImpl(ISessionFactory sf, IAppSessionData appSessionData) { super(sf, appSessionData); } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } protected AccountRequest createAccountRequest(Request request) { return new AccountRequestImpl(request); } protected AccountAnswer createAccountAnswer(Answer answer) { return new AccountAnswerImpl(answer); } @Override public void release() { //stateListeners.clear(); super.release(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/auth/AbortSessionAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.auth; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.Request; import org.jdiameter.api.auth.events.AbortSessionAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AbortSessionAnswerImpl extends AppAnswerEventImpl implements AbortSessionAnswer { private static final long serialVersionUID = 1L; public AbortSessionAnswerImpl(Request request, int authRequestType, long resultCode) { super(request.createAnswer(resultCode)); try { getMessage().getAvps().addAvp(Avp.AUTH_REQUEST_TYPE, authRequestType); } catch (Exception e) { throw new IllegalArgumentException(e); } } /** * @param answer */ public AbortSessionAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public AbortSessionAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public AbortSessionAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public AbortSessionAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/auth/AbortSessionRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.auth; import static org.jdiameter.api.Avp.AUTH_APPLICATION_ID; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Message; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.events.AbortSessionRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AbortSessionRequestImpl extends AppRequestEventImpl implements AbortSessionRequest { private static final long serialVersionUID = 1L; public AbortSessionRequestImpl(AppSession session, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); } public AbortSessionRequestImpl(Message message) { super(message); } @Override public long getAuthApplicationId() throws AvpDataException { Avp authApplicationIdAvp = message.getAvps().getAvp(AUTH_APPLICATION_ID); if (authApplicationIdAvp != null) { return authApplicationIdAvp.getUnsigned32(); } else { throw new AvpDataException("Avp AUTH_APPLICATION_ID not found"); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/auth/AppAuthSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.auth; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.auth.IAuthSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public abstract class AppAuthSessionImpl extends AppSessionImpl implements NetworkReqListener, org.jdiameter.api.app.StateMachine { protected Lock sendAndStateLock = new ReentrantLock(); protected ApplicationId appId; protected transient List stateListeners = new CopyOnWriteArrayList(); // protected SessionFactory sf = null; public AppAuthSessionImpl(ISessionFactory sf, IAuthSessionData sessionData) { super(sf, sessionData); } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } @Override public void release() { //stateListeners.clear(); super.release(); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((appId == null) ? 0 : appId.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } AppAuthSessionImpl other = (AppAuthSessionImpl) obj; if (appId == null) { if (other.appId != null) { return false; } } else if (!appId.equals(other.appId)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/auth/AuthLocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.auth; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.ClientAuthSession; import org.jdiameter.api.auth.ServerAuthSession; import org.jdiameter.client.impl.app.auth.ClientAuthSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.auth.IAuthSessionData; import org.jdiameter.server.impl.app.auth.ServerAuthSessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class AuthLocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IAuthSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientAuthSession.class)) { ClientAuthSessionDataLocalImpl data = new ClientAuthSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerAuthSession.class)) { ServerAuthSessionDataLocalImpl data = new ServerAuthSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } throw new IllegalArgumentException(clazz.toString()); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/auth/AuthSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.auth; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.auth.ClientAuthSession; import org.jdiameter.api.auth.ClientAuthSessionListener; import org.jdiameter.api.auth.ServerAuthSession; import org.jdiameter.api.auth.ServerAuthSessionListener; import org.jdiameter.api.auth.events.AbortSessionAnswer; import org.jdiameter.api.auth.events.AbortSessionRequest; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.auth.events.SessionTermAnswer; import org.jdiameter.api.auth.events.SessionTermRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.auth.ClientAuthSessionImpl; import org.jdiameter.client.impl.app.auth.IClientAuthSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.auth.IAuthMessageFactory; import org.jdiameter.common.api.app.auth.IAuthSessionData; import org.jdiameter.common.api.app.auth.IAuthSessionFactory; import org.jdiameter.common.api.app.auth.IClientAuthActionContext; import org.jdiameter.common.api.app.auth.IServerAuthActionContext; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.server.impl.app.auth.IServerAuthSessionData; import org.jdiameter.server.impl.app.auth.ServerAuthSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default Diameter Authorization Session Factory implementation * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class AuthSessionFactoryImpl implements IAuthSessionFactory, IAuthMessageFactory, ServerAuthSessionListener, ClientAuthSessionListener, IClientAuthActionContext, IServerAuthActionContext, StateChangeListener { private static final long authAppId = 19301L; protected IAuthMessageFactory messageFactory; protected ServerAuthSessionListener serverSessionListener; protected StateChangeListener stateListener; protected ClientAuthSessionListener clientSessionListener; protected boolean stateles; protected long messageTimeout = 5000; protected static final Logger logger = LoggerFactory.getLogger(AuthSessionFactoryImpl.class); protected ISessionDatasource iss; protected ISessionFactory sessionFactory = null; protected IServerAuthActionContext serverSessionContext; protected IClientAuthActionContext clientSessionContext; protected IAppSessionDataFactory sessionDataFactory; public AuthSessionFactoryImpl(SessionFactory sessionFactory) { super(); this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IAuthSessionData.class); } /** * @return the clientSessionContext */ @Override public IClientAuthActionContext getClientSessionContext() { return clientSessionContext != null ? clientSessionContext : this; } /** * @param clientSessionContext the clientSessionContext to set */ @Override public void setClientSessionContext(IClientAuthActionContext clientSessionContext) { this.clientSessionContext = clientSessionContext; } /** * @return the serverSessionContext */ @Override public IServerAuthActionContext getServerSessionContext() { return serverSessionContext != null ? serverSessionContext : this; } /** * @param serverSessionContext the serverSessionContext to set */ @Override public void setServerSessionContext(IServerAuthActionContext serverSessionContext) { this.serverSessionContext = serverSessionContext; } /** * @return the messageTimeout */ @Override public long getMessageTimeout() { return messageTimeout; } /** * @param messageTimeout the messageTimeout to set */ @Override public void setMessageTimeout(long messageTimeout) { this.messageTimeout = messageTimeout; } /** * @return the messageFactory */ @Override public IAuthMessageFactory getMessageFactory() { return messageFactory != null ? messageFactory : this; } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(IAuthMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @return the serverSessionListener */ @Override public ServerAuthSessionListener getServerSessionListener() { return serverSessionListener != null ? serverSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerAuthSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { return stateListener != null ? stateListener : this; } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } /** * @return the clientSessionListener */ @Override public ClientAuthSessionListener getClientSessionListener() { return clientSessionListener != null ? clientSessionListener : this; } /** * @param clientSessionListener the clientSessionListener to set */ @Override public void setClientSessionListener(ClientAuthSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } @Override public boolean isStateles() { return stateles; } @Override public void setStateles(boolean stateles) { this.stateles = stateles; } @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } try { if (aClass == ServerAuthSession.class) { IServerAuthSessionData sessionData = (IServerAuthSessionData) this.sessionDataFactory .getAppSessionData(ServerAuthSession.class, sessionId); ServerAuthSessionImpl session = new ServerAuthSessionImpl(sessionData, sessionFactory, getServerSessionListener(), getMessageFactory(), getStateListener(), getServerSessionContext(), messageTimeout, isStateles()); session.getSessions().get(0).setRequestListener(session); return session; } else { if (aClass == ClientAuthSession.class) { IClientAuthSessionData sessionData = (IClientAuthSessionData) this.sessionDataFactory .getAppSessionData(ClientAuthSession.class, sessionId); ClientAuthSessionImpl session = new ClientAuthSessionImpl(sessionData, sessionFactory, getClientSessionListener(), getMessageFactory(), getStateListener(), getClientSessionContext(), isStateles()); session.getSessions().get(0).setRequestListener(session); return session; } } } catch (Exception e) { logger.error("Failure trying to obtain new authorization session", e); } return null; } @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { try { if (aClass == ServerAuthSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerAuthSessionData sessionData = (IServerAuthSessionData) this.sessionDataFactory .getAppSessionData(ServerAuthSession.class, sessionId); sessionData.setApplicationId(applicationId); ServerAuthSessionImpl session = new ServerAuthSessionImpl(sessionData, sessionFactory, getServerSessionListener(), getMessageFactory(), getStateListener(), getServerSessionContext(), messageTimeout, isStateles()); iss.addSession(session); session.getSessions().get(0).setRequestListener(session); return session; } else { if (aClass == ClientAuthSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientAuthSessionData sessionData = (IClientAuthSessionData) this.sessionDataFactory .getAppSessionData(ClientAuthSession.class, sessionId); sessionData.setApplicationId(applicationId); ClientAuthSessionImpl session = new ClientAuthSessionImpl(sessionData, sessionFactory, getClientSessionListener(), getMessageFactory(), getStateListener(), getClientSessionContext(), isStateles()); iss.addSession(session); // iss.setSessionListener(clientSession.getSessionId(), (NetworkReqListener) appSession); session.getSessions().get(0).setRequestListener(session); return session; } } } catch (Exception e) { logger.error("Failure trying to obtain new authorization session", e); } return null; } // Message Factory Methods ------------------------------------------------ @Override public AppAnswerEvent createAuthAnswer(Answer answer) { return new AppAnswerEventImpl(answer); } @Override public AppRequestEvent createAuthRequest(Request request) { return new AppRequestEventImpl(request); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.auth.IAuthMessageFactory#getAuthMessageCommandCode() */ @Override public int getAuthMessageCommandCode() { return 258; } @Override public ApplicationId getApplicationId() { return ApplicationId.createByAuthAppId(authAppId); } // Message Handlers ------------------------------------------------------- @Override public void doAbortSessionRequestEvent(ClientAuthSession appSession, AbortSessionRequest asr) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AuthorizationSessionFactory :: doAbortSessionRequestEvent :: appSession[{}], ASR[{}]", appSession, asr); } @Override public void doAbortSessionAnswerEvent(ServerAuthSession appSession, AbortSessionAnswer asa) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AuthorizationSessionFactory :: doAbortSessionAnswerEvent :: appSession[{}], ASA[{}]", appSession, asa); } @Override public void doSessionTerminationRequestEvent(ServerAuthSession appSession, SessionTermRequest str) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AuthorizationSessionFactory :: doSessionTerminationRequestEvent :: appSession[{}], STR[{}]", appSession, str); } @Override public void doSessionTerminationAnswerEvent(ClientAuthSession appSession, SessionTermAnswer sta) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AuthorizationSessionFactory :: doSessionTerminationAnswerEvent :: appSession[{}], STA[{}]", appSession, sta); } @Override public void doAuthRequestEvent(ServerAuthSession appSession, AppRequestEvent request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AuthorizationSessionFactory :: doAuthRequestEvent :: appSession[{}], Request[{}]", appSession, request); } @Override public void doAuthAnswerEvent(ClientAuthSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AuthorizationSessionFactory :: doAuthAnswerEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doReAuthRequestEvent(ClientAuthSession appSession, ReAuthRequest rar) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AuthorizationSessionFactory :: doReAuthRequestEvent :: appSession[{}], RAR[{}]", appSession, rar); } @Override public void doReAuthAnswerEvent(ServerAuthSession appSession, ReAuthRequest rar, ReAuthAnswer raa) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AuthorizationSessionFactory :: doReAuthAnswerEvent :: appSession[{}], RAR[{}], RAA[{}]", new Object[] { appSession, rar, raa }); } @Override public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base AuthorizationSessionFactory :: doOtherEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } // State Change Listener -------------------------------------------------- @Override @SuppressWarnings("unchecked") public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter Base AuthorizationSessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override @SuppressWarnings("unchecked") public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter Base AuthorizationSessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } // Context Methods -------------------------------------------------------- /* * (non-Javadoc) * * @seeorg.jdiameter.common.api.app.auth.IClientAuthActionContext#accessTimeoutElapses(org.jdiameter.api.auth. * ClientAuthSession) */ @Override public void accessTimeoutElapses(ClientAuthSession session) throws InternalException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.auth.IClientAuthActionContext#createAccessTimer() */ @Override public long getAccessTimeout() throws InternalException { return 20000; } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.auth.IClientAuthActionContext#disconnectUserOrDev(org.jdiameter.api.auth.ClientAuthSession, * org.jdiameter.api.Message) */ @Override public void disconnectUserOrDev(ClientAuthSession session, Message request) throws InternalException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @seeorg.jdiameter.common.api.app.auth.IServerAuthActionContext# * accessTimeoutElapses(org.jdiameter.api.auth.ServerAuthSession) */ @Override public void accessTimeoutElapses(ServerAuthSession session) throws InternalException { // TODO Auto-generated method stub } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/auth/ReAuthAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.auth; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ReAuthAnswerImpl extends AppAnswerEventImpl implements ReAuthAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public ReAuthAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public ReAuthAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public ReAuthAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public ReAuthAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/auth/ReAuthRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.auth; import static org.jdiameter.api.Avp.AUTH_APPLICATION_ID; import static org.jdiameter.api.Avp.RE_AUTH_REQUEST_TYPE; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Message; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ReAuthRequestImpl extends AppRequestEventImpl implements ReAuthRequest { private static final long serialVersionUID = 1L; public ReAuthRequestImpl(Message message) { super(message); } @Override public long getAuthApplicationId() throws AvpDataException { Avp authApplicationIdAvp = message.getAvps().getAvp(AUTH_APPLICATION_ID); if (authApplicationIdAvp != null) { return authApplicationIdAvp.getUnsigned32(); } else { throw new AvpDataException("Avp AUTH_APPLICATION_ID not found"); } } @Override public int getReAuthRequestType() throws AvpDataException { Avp reAuthRequestTypeAvp = message.getAvps().getAvp(RE_AUTH_REQUEST_TYPE); if (reAuthRequestTypeAvp != null) { return reAuthRequestTypeAvp.getInteger32(); } else { throw new AvpDataException("Avp RE_AUTH_REQUEST_TYPE not found"); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/auth/SessionTermAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.auth; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.auth.events.SessionTermAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class SessionTermAnswerImpl extends AppAnswerEventImpl implements SessionTermAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public SessionTermAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public SessionTermAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public SessionTermAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public SessionTermAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/auth/SessionTermRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.auth; import static org.jdiameter.api.Avp.AUTH_APPLICATION_ID; import static org.jdiameter.api.Avp.TERMINATION_CAUSE; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Message; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.events.SessionTermRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class SessionTermRequestImpl extends AppRequestEventImpl implements SessionTermRequest { private static final long serialVersionUID = 1L; public SessionTermRequestImpl(AppSession session, int terminationCause, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); message.getAvps().addAvp(Avp.TERMINATION_CAUSE, terminationCause, true, false); } public SessionTermRequestImpl(Message message) { super(message); } @Override public long getAuthApplicationId() throws AvpDataException { Avp authApplicationIdAvp = message.getAvps().getAvp(AUTH_APPLICATION_ID); if (authApplicationIdAvp != null) { return authApplicationIdAvp.getUnsigned32(); } else { throw new AvpDataException("Avp AUTH_APPLICATION_ID not found"); } } @Override public int getTerminationCause() throws AvpDataException { Avp terminationCauseAvp = message.getAvps().getAvp(TERMINATION_CAUSE); if (terminationCauseAvp != null) { return terminationCauseAvp.getInteger32(); } else { throw new AvpDataException("Avp TERMINATION_CAUSE not found"); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/AppCCASessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cca; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.cca.CCASession; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public abstract class AppCCASessionImpl extends AppSessionImpl implements CCASession, NetworkReqListener { protected Lock sendAndStateLock = new ReentrantLock(); //FIXME: those must be recreated from local resources! //FIXME: change this to single ref! //FIXME: use FastList ? protected List stateListeners = new CopyOnWriteArrayList(); public AppCCASessionImpl(ISessionFactory sf, IAppSessionData data) { super(sf, data); } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } @Override public void release() { //stateListeners.clear(); super.release(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/CCALocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cca; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.cca.ClientCCASession; import org.jdiameter.api.cca.ServerCCASession; import org.jdiameter.client.impl.app.cca.ClientCCASessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.cca.ICCASessionData; import org.jdiameter.server.impl.app.cca.ServerCCASessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class CCALocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public ICCASessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientCCASession.class)) { ClientCCASessionDataLocalImpl data = new ClientCCASessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerCCASession.class)) { ServerCCASessionDataLocalImpl data = new ServerCCASessionDataLocalImpl(); data.setSessionId(sessionId); return data; } throw new IllegalArgumentException(clazz.toString()); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/CCASessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.cca; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.Request; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.cca.ClientCCASession; import org.jdiameter.api.cca.ClientCCASessionListener; import org.jdiameter.api.cca.ServerCCASession; import org.jdiameter.api.cca.ServerCCASessionListener; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.cca.ClientCCASessionImpl; import org.jdiameter.client.impl.app.cca.IClientCCASessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.cca.ICCAMessageFactory; import org.jdiameter.common.api.app.cca.ICCASessionData; import org.jdiameter.common.api.app.cca.ICCASessionFactory; import org.jdiameter.common.api.app.cca.IClientCCASessionContext; import org.jdiameter.common.api.app.cca.IServerCCASessionContext; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.auth.ReAuthAnswerImpl; import org.jdiameter.common.impl.app.auth.ReAuthRequestImpl; import org.jdiameter.server.impl.app.cca.IServerCCASessionData; import org.jdiameter.server.impl.app.cca.ServerCCASessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class CCASessionFactoryImpl implements ICCASessionFactory, ClientCCASessionListener, ServerCCASessionListener, StateChangeListener, ICCAMessageFactory, IServerCCASessionContext, IClientCCASessionContext { // Message timeout value (in milliseconds) protected int defaultDirectDebitingFailureHandling = 0; protected int defaultCreditControlFailureHandling = 0; // its seconds protected long defaultValidityTime = 60; protected long defaultTxTimerValue = 30; // local not replicated listeners: protected ClientCCASessionListener clientSessionListener; protected ServerCCASessionListener serverSessionListener; protected StateChangeListener stateListener; protected IServerCCASessionContext serverContextListener; protected IClientCCASessionContext clientContextListener; protected ICCAMessageFactory messageFactory; protected static final Logger logger = LoggerFactory.getLogger(CCASessionFactoryImpl.class); protected ISessionDatasource iss; protected ISessionFactory sessionFactory = null; protected IAppSessionDataFactory sessionDataFactory; public CCASessionFactoryImpl() { } ; public CCASessionFactoryImpl(SessionFactory sessionFactory) { super(); init(sessionFactory); } /** * @param sessionFactory2 */ public void init(SessionFactory sessionFactory) { this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(ICCASessionData.class); if (this.sessionDataFactory == null) { logger.debug("No factory for CCA Application data, using default/local."); this.sessionDataFactory = new CCALocalSessionDataFactory(); } } public CCASessionFactoryImpl(SessionFactory sessionFactory, int defaultDirectDebitingFailureHandling, int defaultCreditControlFailureHandling, long defaultValidityTime, long defaultTxTimerValue) { this(sessionFactory); this.defaultDirectDebitingFailureHandling = defaultDirectDebitingFailureHandling; this.defaultCreditControlFailureHandling = defaultCreditControlFailureHandling; this.defaultValidityTime = defaultValidityTime; this.defaultTxTimerValue = defaultTxTimerValue; } /** * @return the clientSessionListener */ @Override public ClientCCASessionListener getClientSessionListener() { if (clientSessionListener != null) { return clientSessionListener; } else { return this; } } /** * @param clientSessionListener the clientSessionListener to set */ @Override public void setClientSessionListener(ClientCCASessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the serverSessionListener */ @Override public ServerCCASessionListener getServerSessionListener() { if (serverSessionListener != null) { return serverSessionListener; } else { return this; } } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerCCASessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the serverContextListener */ @Override public IServerCCASessionContext getServerContextListener() { if (serverContextListener != null) { return serverContextListener; } else { return this; } } /** * @param serverContextListener the serverContextListener to set */ @Override public void setServerContextListener(IServerCCASessionContext serverContextListener) { this.serverContextListener = serverContextListener; } /** * @return the clientContextListener */ @Override public IClientCCASessionContext getClientContextListener() { if (clientContextListener != null) { return clientContextListener; } else { return this; } } /** * @return the messageFactory */ @Override public ICCAMessageFactory getMessageFactory() { if (messageFactory != null) { return messageFactory; } else { return this; } } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(ICCAMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @param clientContextListener the clientContextListener to set */ @Override public void setClientContextListener(IClientCCASessionContext clientContextListener) { this.clientContextListener = clientContextListener; } /** * @return the sessionFactory */ public SessionFactory getSessionFactory() { return sessionFactory; } /** * @param sessionFactory the sessionFactory to set */ public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = (ISessionFactory) sessionFactory; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { if (this.stateListener != null) { return stateListener; } else { return this; } } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ClientCCASession.class) { ClientCCASessionImpl clientSession = null; IClientCCASessionData data = (IClientCCASessionData) this.sessionDataFactory .getAppSessionData(ClientCCASession.class, sessionId); clientSession = new ClientCCASessionImpl(data, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerCCASession.class) { ServerCCASessionImpl serverSession = null; IServerCCASessionData data = (IServerCCASessionData) this.sessionDataFactory .getAppSessionData(ServerCCASession.class, sessionId); serverSession = new ServerCCASessionImpl(data, this.getMessageFactory(), sessionFactory, this.getServerSessionListener(), this.getServerContextListener(), this.getStateListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientCCASession.class + "," + ServerCCASession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Credit-Control Session.", e); } return appSession; } @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; try { //TODO: add check to test if session exists. if (aClass == ClientCCASession.class) { ClientCCASessionImpl clientSession = null; if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientCCASessionData data = (IClientCCASessionData) this.sessionDataFactory .getAppSessionData(ClientCCASession.class, sessionId); data.setApplicationId(applicationId); clientSession = new ClientCCASessionImpl(data, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); // this goes first! iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerCCASession.class) { ServerCCASessionImpl serverSession = null; if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerCCASessionData data = (IServerCCASessionData) this.sessionDataFactory .getAppSessionData(ServerCCASession.class, sessionId); data.setApplicationId(applicationId); serverSession = new ServerCCASessionImpl(data, this.getMessageFactory(), sessionFactory, this.getServerSessionListener(), this.getServerContextListener(), this.getStateListener()); iss.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientCCASession.class + "," + ServerCCASession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Credit-Control Session.", e); } return appSession; } // default implementation of methods so there are no exception! // ------------------------------------------------ // Message Handlers --------------------------------------------------------- @Override public void doCreditControlRequest(ServerCCASession session, JCreditControlRequest request) throws InternalException { } @Override public void doCreditControlAnswer(ClientCCASession session, JCreditControlRequest request, JCreditControlAnswer answer) throws InternalException { } @Override public void doReAuthRequest(ClientCCASession session, ReAuthRequest request) throws InternalException { } @Override public void doReAuthAnswer(ServerCCASession session, ReAuthRequest request, ReAuthAnswer answer) throws InternalException { } @Override public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { } // Message Factory Methods -------------------------------------------------- @Override public JCreditControlAnswer createCreditControlAnswer(Answer answer) { return new JCreditControlAnswerImpl(answer); } @Override public JCreditControlRequest createCreditControlRequest(Request req) { return new JCreditControlRequestImpl(req); } @Override public ReAuthAnswer createReAuthAnswer(Answer answer) { return new ReAuthAnswerImpl(answer); } @Override public ReAuthRequest createReAuthRequest(Request req) { return new ReAuthRequestImpl(req); } // Context Methods ---------------------------------------------------------- @Override public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter CCA SessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter CCA SessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } // FIXME: add ctx methods proxy calls! @Override public void sessionSupervisionTimerExpired(ServerCCASession session) { // this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session); session.release(); } @Override public void sessionSupervisionTimerReStarted(ServerCCASession session, ScheduledFuture future) { // TODO Complete this method. } @Override public void sessionSupervisionTimerStarted(ServerCCASession session, ScheduledFuture future) { // TODO Complete this method. } @Override public void sessionSupervisionTimerStopped(ServerCCASession session, ScheduledFuture future) { // TODO Complete this method. } @Override public void timeoutExpired(Request request) { // FIXME What should we do when there's a timeout? } @Override public void denyAccessOnDeliverFailure(ClientCCASession clientCCASessionImpl, Message request) { // TODO Complete this method. } @Override public void denyAccessOnFailureMessage(ClientCCASession clientCCASessionImpl) { // TODO Complete this method. } @Override public void denyAccessOnTxExpire(ClientCCASession clientCCASessionImpl) { clientCCASessionImpl.release(); } @Override public int getDefaultCCFHValue() { return defaultCreditControlFailureHandling; } @Override public int getDefaultDDFHValue() { return defaultDirectDebitingFailureHandling; } @Override public long getDefaultTxTimerValue() { return defaultTxTimerValue; } @Override public void grantAccessOnDeliverFailure(ClientCCASession clientCCASessionImpl, Message request) { // TODO Auto-generated method stub } @Override public void grantAccessOnFailureMessage(ClientCCASession clientCCASessionImpl) { // TODO Auto-generated method stub } @Override public void grantAccessOnTxExpire(ClientCCASession clientCCASessionImpl) { // TODO Auto-generated method stub } @Override public void indicateServiceError(ClientCCASession clientCCASessionImpl) { // TODO Auto-generated method stub } @Override public void txTimerExpired(ClientCCASession session) { // this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session); session.release(); } @Override public long[] getApplicationIds() { // FIXME: What should we do here? return new long[] { 4 }; } @Override public long getDefaultValidityTime() { return this.defaultValidityTime; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/JCreditControlAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.cca; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JCreditControlAnswerImpl extends AppAnswerEventImpl implements JCreditControlAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(JCreditControlAnswerImpl.class); private static final int CREDIT_CONTROL_FAILURE_HANDLING_AVP_CODE = 427; private static final int DIRECT_DEBITING_FAILURE_HANDLING_AVP_CODE = 428; private static final int REQUESTED_ACTION_AVP_CODE = 436; private static final int CC_REQUEST_TYPE_AVP_CODE = 416; private static final int VALIDITY_TIME_AVP_CODE = 448; /** * @param answer */ public JCreditControlAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public JCreditControlAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public JCreditControlAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public JCreditControlAnswerImpl(Request request) { super(request); } @Override public boolean isCreditControlFailureHandlingAVPPresent() { return super.message.getAvps().getAvp(CREDIT_CONTROL_FAILURE_HANDLING_AVP_CODE) != null; } @Override public int getCredidControlFailureHandlingAVPValue() { Avp credidControlFailureHandlingAvp = super.message.getAvps().getAvp(CREDIT_CONTROL_FAILURE_HANDLING_AVP_CODE); if (credidControlFailureHandlingAvp != null) { try { return credidControlFailureHandlingAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e); } } return -1; } @Override public boolean isDirectDebitingFailureHandlingAVPPresent() { return super.message.getAvps().getAvp(DIRECT_DEBITING_FAILURE_HANDLING_AVP_CODE) != null; } @Override public int getDirectDebitingFailureHandlingAVPValue() { Avp directDebitingFailureHandlingAvp = super.message.getAvps().getAvp(DIRECT_DEBITING_FAILURE_HANDLING_AVP_CODE); if (directDebitingFailureHandlingAvp != null) { try { return directDebitingFailureHandlingAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Direct-Debiting-Failure-Handling AVP value", e); } } return -1; } @Override public Avp getValidityTimeAvp() { Avp validityAvp = super.message.getAvps().getAvp(VALIDITY_TIME_AVP_CODE); if (validityAvp == null) { Avp mscc = super.message.getAvps().getAvp(Avp.MULTIPLE_SERVICES_CREDIT_CONTROL); try { validityAvp = mscc != null ? mscc.getGrouped().getAvp(Avp.VALIDITY_TIME) : null; } catch (AvpDataException ex) { validityAvp = null; } } return validityAvp; } @Override public boolean isRequestTypeAVPPresent() { return super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE) != null; } @Override public int getRequestTypeAVPValue() { Avp requestTypeAvp = super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE); if (requestTypeAvp != null) { try { return requestTypeAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain CC-Request-Type AVP value", e); } } return -1; } public boolean isRequestedActionAVPPresent() { return super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE) != null; } public int getRequestedActionAVPValue() { Avp requestedActionAvp = super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE); if (requestedActionAvp != null) { try { return requestedActionAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Requested-Action AVP value", e); } } return -1; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cca/JCreditControlRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.cca; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.cca.events.JCreditControlRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JCreditControlRequestImpl extends AppRequestEventImpl implements JCreditControlRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(JCreditControlRequestImpl.class); private static final int REQUESTED_ACTION_AVP_CODE = 436; private static final int CC_REQUEST_TYPE_AVP_CODE = 416; public JCreditControlRequestImpl(AppSession session, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); } public JCreditControlRequestImpl(Request request) { super(request); } @Override public boolean isRequestedActionAVPPresent() { return super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE) != null; } @Override public int getRequestedActionAVPValue() { Avp requestedActionAvp = super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE); if (requestedActionAvp != null) { try { return requestedActionAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Requested-Action AVP value", e); } } return -1; } @Override public boolean isRequestTypeAVPPresent() { return super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE) != null; } @Override public int getRequestTypeAVPValue() { Avp requestTypeAvp = super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE); if (requestTypeAvp != null) { try { return requestTypeAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain CC-Request-Type AVP value", e); } } return -1; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/CxDxLocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.cxdx.ClientCxDxSession; import org.jdiameter.api.cxdx.ServerCxDxSession; import org.jdiameter.client.impl.app.cxdx.ClientCxDxSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; import org.jdiameter.server.impl.app.cxdx.ServerCxDxSessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class CxDxLocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public ICxDxSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientCxDxSession.class)) { ClientCxDxSessionDataLocalImpl data = new ClientCxDxSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerCxDxSession.class)) { ServerCxDxSessionDataLocalImpl data = new ServerCxDxSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } throw new IllegalArgumentException(clazz.toString()); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/CxDxLocalSessionDataImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.cxdx.CxDxSessionState; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class CxDxLocalSessionDataImpl extends AppSessionDataLocalImpl implements ICxDxSessionData { protected CxDxSessionState state = CxDxSessionState.IDLE; protected Request buffer; protected Serializable tsTimerId; /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#setCxDxSessionState(org.jdiameter.common.api.app.cxdx. * CxDxSessionState) */ @Override public void setCxDxSessionState(CxDxSessionState state) { this.state = state; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#getCxDxSessionState() */ @Override public CxDxSessionState getCxDxSessionState() { return this.state; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#getTsTimerId() */ @Override public Serializable getTsTimerId() { return this.tsTimerId; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#setTsTimerId(java.io.Serializable) */ @Override public void setTsTimerId(Serializable tid) { this.tsTimerId = tid; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#setBuffer(org.jdiameter.api.Message) */ @Override public void setBuffer(Request buffer) { this.buffer = buffer; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#getBuffer() */ @Override public Request getBuffer() { return this.buffer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/CxDxSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import java.io.Serializable; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public abstract class CxDxSession extends AppSessionImpl implements NetworkReqListener, StateMachine { public static final int _TX_TIMEOUT = 30 * 1000; protected Lock sendAndStateLock = new ReentrantLock(); protected transient List stateListeners = new CopyOnWriteArrayList(); protected transient ICxDxMessageFactory messageFactory; //protected CxDxSessionState state = CxDxSessionState.IDLE; // protected Future timeoutTaskFuture; // this can be weird //protected Serializable timerId_timeout; protected static final String TIMER_NAME_MSG_TIMEOUT = "MSG_TIMEOUT"; //protected Message buffer; protected ICxDxSessionData sessionData; public CxDxSession(ISessionFactory sf, ICxDxSessionData sessionData) { super(sf, sessionData); this.sessionData = sessionData; } @Override @SuppressWarnings("unchecked") public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override @SuppressWarnings("unchecked") public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } @Override public boolean isStateless() { // Cx/Dx is always stateless return true; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { // Cx/Dx is event based.. return false; } @Override public void release() { //stateListeners.clear(); super.release(); } protected void startMsgTimer() { try { sendAndStateLock.lock(); sessionData.setTsTimerId(super.timerFacility.schedule(getSessionId(), TIMER_NAME_MSG_TIMEOUT, _TX_TIMEOUT)); } finally { sendAndStateLock.unlock(); } } protected void cancelMsgTimer() { try { sendAndStateLock.lock(); final Serializable timerId = this.sessionData.getTsTimerId(); if (timerId == null) { return; } super.timerFacility.cancel(timerId); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } CxDxSession other = (CxDxSession) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/CxDxSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.acc.ClientAccSession; import org.jdiameter.api.acc.ServerAccSession; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.cxdx.ClientCxDxSession; import org.jdiameter.api.cxdx.ClientCxDxSessionListener; import org.jdiameter.api.cxdx.ServerCxDxSession; import org.jdiameter.api.cxdx.ServerCxDxSessionListener; import org.jdiameter.api.cxdx.events.JLocationInfoAnswer; import org.jdiameter.api.cxdx.events.JLocationInfoRequest; import org.jdiameter.api.cxdx.events.JMultimediaAuthAnswer; import org.jdiameter.api.cxdx.events.JMultimediaAuthRequest; import org.jdiameter.api.cxdx.events.JPushProfileAnswer; import org.jdiameter.api.cxdx.events.JPushProfileRequest; import org.jdiameter.api.cxdx.events.JRegistrationTerminationAnswer; import org.jdiameter.api.cxdx.events.JRegistrationTerminationRequest; import org.jdiameter.api.cxdx.events.JServerAssignmentAnswer; import org.jdiameter.api.cxdx.events.JServerAssignmentRequest; import org.jdiameter.api.cxdx.events.JUserAuthorizationAnswer; import org.jdiameter.api.cxdx.events.JUserAuthorizationRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.cxdx.CxDxClientSessionImpl; import org.jdiameter.client.impl.app.cxdx.IClientCxDxSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; import org.jdiameter.common.api.app.cxdx.ICxDxSessionFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.cxdx.CxDxServerSessionImpl; import org.jdiameter.server.impl.app.cxdx.IServerCxDxSessionData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class CxDxSessionFactoryImpl implements ICxDxSessionFactory, ClientCxDxSessionListener, ServerCxDxSessionListener, ICxDxMessageFactory, StateChangeListener { private static final Logger logger = LoggerFactory.getLogger(CxDxSessionFactoryImpl.class); protected ISessionFactory sessionFactory; protected ClientCxDxSessionListener clientSessionListener; protected ServerCxDxSessionListener serverSessionListener; protected ICxDxMessageFactory messageFactory; protected StateChangeListener stateListener; protected ISessionDatasource iss; protected IAppSessionDataFactory sessionDataFactory; public CxDxSessionFactoryImpl(SessionFactory sessionFactory) { super(); this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(ICxDxSessionData.class); } /** * @return the clientSessionListener */ @Override public ClientCxDxSessionListener getClientSessionListener() { if (clientSessionListener != null) { return clientSessionListener; } else { return this; } } /** * @param clientSessionListener the clientSessionListener to set */ @Override public void setClientSessionListener(ClientCxDxSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the serverSessionListener */ @Override public ServerCxDxSessionListener getServerSessionListener() { if (serverSessionListener != null) { return serverSessionListener; } else { return this; } } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerCxDxSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the messageFactory */ @Override public ICxDxMessageFactory getMessageFactory() { if (messageFactory != null) { return messageFactory; } else { return this; } } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(ICxDxMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { if (stateListener != null) { return stateListener; } else { return this; } } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ClientCxDxSession.class) { IClientCxDxSessionData sessionData = (IClientCxDxSessionData) this.sessionDataFactory .getAppSessionData(ClientCxDxSession.class, sessionId); CxDxClientSessionImpl clientSession = new CxDxClientSessionImpl(sessionData, this.getMessageFactory(), this.sessionFactory, this.getClientSessionListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerCxDxSession.class) { IServerCxDxSessionData sessionData = (IServerCxDxSessionData) this.sessionDataFactory .getAppSessionData(ServerCxDxSession.class, sessionId); CxDxServerSessionImpl serverSession = new CxDxServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientAccSession.class + "," + ServerAccSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Cx/Dx Session.", e); } return appSession; } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.IAppSessionFactory#getNewSession(java.lang * .String, java.lang.Class, org.jdiameter.api.ApplicationId, * java.lang.Object[]) */ @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; if (aClass == ClientCxDxSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientCxDxSessionData sessionData = (IClientCxDxSessionData) this.sessionDataFactory .getAppSessionData(ClientCxDxSession.class, sessionId); sessionData.setApplicationId(applicationId); CxDxClientSessionImpl clientSession = new CxDxClientSessionImpl(sessionData, this.getMessageFactory(), this.sessionFactory, this .getClientSessionListener()); iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerCxDxSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerCxDxSessionData sessionData = (IServerCxDxSessionData) this.sessionDataFactory .getAppSessionData(ServerCxDxSession.class, sessionId); sessionData.setApplicationId(applicationId); CxDxServerSessionImpl serverSession = new CxDxServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); iss.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ServerCxDxSession.class + "," + ClientCxDxSession.class + "]"); } return appSession; } // Cx/Dx Message Factory Methods ------------------------------------------ /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createLocationInfoAnswer(org.jdiameter.api.Answer) */ @Override public JLocationInfoAnswer createLocationInfoAnswer(Answer answer) { return new JLocationInfoAnswerImpl(answer); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createLocationInfoRequest(org.jdiameter.api.Request) */ @Override public JLocationInfoRequest createLocationInfoRequest(Request request) { return new JLocationInfoRequestImpl(request); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createMultimediaAuthAnswer(org.jdiameter.api.Answer) */ @Override public JMultimediaAuthAnswer createMultimediaAuthAnswer(Answer answer) { return new JMultimediaAuthAnswerImpl(answer); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createMultimediaAuthRequest(org.jdiameter.api.Request) */ @Override public JMultimediaAuthRequest createMultimediaAuthRequest(Request request) { return new JMultimediaAuthRequestImpl(request); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createPushProfileAnswer(org.jdiameter.api.Answer) */ @Override public JPushProfileAnswer createPushProfileAnswer(Answer answer) { return new JPushProfileAnswerImpl(answer); } /* * (non-Javadoc) * * @seeorg.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createPushProfileRequest(org.jdiameter.api.Request) */ @Override public JPushProfileRequest createPushProfileRequest(Request request) { return new JPushProfileRequestImpl(request); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createRegistrationTerminationAnswer(org.jdiameter.api.Answer) */ @Override public JRegistrationTerminationAnswer createRegistrationTerminationAnswer(Answer answer) { return new JRegistrationTerminationAnswerImpl(answer); } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createRegistrationTerminationRequest(org.jdiameter.api.Request) */ @Override public JRegistrationTerminationRequest createRegistrationTerminationRequest(Request request) { return new JRegistrationTerminationRequestImpl(request); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createServerAssignmentAnswer(org.jdiameter.api.Answer) */ @Override public JServerAssignmentAnswer createServerAssignmentAnswer(Answer answer) { return new JServerAssignmentAnswerImpl(answer); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createServerAssignmentRequest(org.jdiameter.api.Request) */ @Override public JServerAssignmentRequest createServerAssignmentRequest(Request request) { return new JServerAssignmentRequestImpl(request); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createUserAuthorizationAnswer(org.jdiameter.api.Answer) */ @Override public JUserAuthorizationAnswer createUserAuthorizationAnswer(Answer answer) { return new JUserAuthorizationAnswerImpl(answer); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#createUserAuthorizationRequest(org.jdiameter.api.Request) */ @Override public JUserAuthorizationRequest createUserAuthorizationRequest(Request request) { return new JUserAuthorizationRequestImpl(request); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory#getApplicationId() */ @Override public long getApplicationId() { return 16777216; } // Session Listeners -------------------------------------------------------- /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSessionListener#doLocationInformationRequest( * org.jdiameter.api.cxdx.ServerCxDxSession, org.jdiameter.api.cxdx.events.JLocationInfoRequest) */ @Override public void doLocationInformationRequest(ServerCxDxSession appSession, JLocationInfoRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doLocationInformationRequest :: appSession[{}], Request[{}]", appSession, request); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSessionListener#doMultimediaAuthRequest( * org.jdiameter.api.cxdx.ServerCxDxSession, org.jdiameter.api.cxdx.events.JMultimediaAuthRequest) */ @Override public void doMultimediaAuthRequest(ServerCxDxSession appSession, JMultimediaAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doMultimediaAuthRequest :: appSession[{}], Request[{}]", appSession, request); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSessionListener#doOtherEvent(org.jdiameter.api.app.AppSession, * org.jdiameter.api.app.AppRequestEvent, org.jdiameter.api.app.AppAnswerEvent) */ @Override public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doOtherEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSessionListener#doPushProfileAnswer(org.jdiameter.api.cxdx.ServerCxDxSession, * org.jdiameter.api.cxdx.events.JPushProfileRequest, org.jdiameter.api.cxdx.events.JPushProfileAnswer) */ @Override public void doPushProfileAnswer(ServerCxDxSession appSession, JPushProfileRequest request, JPushProfileAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doPushProfileAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSessionListener#doRegistrationTerminationAnswer(org.jdiameter.api.cxdx. * ServerCxDxSession, * org.jdiameter.api.cxdx.events.JRegistrationTerminationRequest, * org.jdiameter.api.cxdx.events.JRegistrationTerminationAnswer) */ @Override public void doRegistrationTerminationAnswer(ServerCxDxSession appSession, JRegistrationTerminationRequest request, JRegistrationTerminationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info( "Diameter Cx/Dx Session Factory :: doRegistrationTerminationAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } /* * (non-Javadoc) * * @see * org.jdiameter.api.cxdx.ServerCxDxSessionListener#doServerAssignmentRequest( * org.jdiameter.api.cxdx.ServerCxDxSession, org.jdiameter.api.cxdx.events.JServerAssignmentRequest) */ @Override public void doServerAssignmentRequest(ServerCxDxSession appSession, JServerAssignmentRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doServerAssignmentRequest :: appSession[{}], Request[{}]", appSession, request); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSessionListener#doUserAuthorizationRequest( * org.jdiameter.api.cxdx.ServerCxDxSession, org.jdiameter.api.cxdx.events.JUserAuthorizationRequest) */ @Override public void doUserAuthorizationRequest(ServerCxDxSession appSession, JUserAuthorizationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doUserAuthorizationRequest :: appSession[{}], Request[{}]", appSession, request); } /* * (non-Javadoc) * * @see * org.jdiameter.api.cxdx.ClientCxDxSessionListener#doLocationInformationAnswer(org.jdiameter.api.cxdx.ClientCxDxSession, * org.jdiameter.api.cxdx.events.JLocationInfoRequest, org.jdiameter.api.cxdx.events.JLocationInfoAnswer) */ @Override public void doLocationInformationAnswer(ClientCxDxSession appSession, JLocationInfoRequest request, JLocationInfoAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doLocationInformationAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ClientCxDxSessionListener#doMultimediaAuthAnswer(org.jdiameter.api.cxdx.ClientCxDxSession, * org.jdiameter.api.cxdx.events.JMultimediaAuthRequest, org.jdiameter.api.cxdx.events.JMultimediaAuthAnswer) */ @Override public void doMultimediaAuthAnswer(ClientCxDxSession appSession, JMultimediaAuthRequest request, JMultimediaAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doMultimediaAuthAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ClientCxDxSessionListener#doPushProfileRequest( * org.jdiameter.api.cxdx.ClientCxDxSession, org.jdiameter.api.cxdx.events.JPushProfileRequest) */ @Override public void doPushProfileRequest(ClientCxDxSession appSession, JPushProfileRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doPushProfileRequest :: appSession[{}], Request[{}]", appSession, request); } /* * (non-Javadoc) * * @seeorg.jdiameter.api.cxdx.ClientCxDxSessionListener#doRegistrationTerminationRequest( * org.jdiameter.api.cxdx.ClientCxDxSession, org.jdiameter.api.cxdx.events.JRegistrationTerminationRequest) */ @Override public void doRegistrationTerminationRequest(ClientCxDxSession appSession, JRegistrationTerminationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doRegistrationTerminationRequest :: appSession[{}], Request[{}]", appSession, request); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ClientCxDxSessionListener#doServerAssignmentAnswer(org.jdiameter.api.cxdx.ClientCxDxSession, * org.jdiameter.api.cxdx.events.JServerAssignmentRequest, org.jdiameter.api.cxdx.events.JServerAssignmentAnswer) */ @Override public void doServerAssignmentAnswer(ClientCxDxSession appSession, JServerAssignmentRequest request, JServerAssignmentAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doServerAssignmentAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ClientCxDxSessionListener#doUserAuthorizationAnswer(org.jdiameter.api.cxdx.ClientCxDxSession, * org.jdiameter.api.cxdx.events.JUserAuthorizationRequest, org.jdiameter.api.cxdx.events.JUserAuthorizationAnswer) */ @Override public void doUserAuthorizationAnswer(ClientCxDxSession appSession, JUserAuthorizationRequest request, JUserAuthorizationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Cx/Dx Session Factory :: doUserAuthorizationAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Enum, java.lang.Enum) */ @Override @SuppressWarnings("unchecked") public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter Cx/Dx Session Factory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override @SuppressWarnings("unchecked") public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter Cx/Dx Session Factory :: stateChanged :: Session, [{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JLocationInfoAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.cxdx.events.JLocationInfoAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JLocationInfoAnswerImpl extends AppAnswerEventImpl implements JLocationInfoAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JLocationInfoAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public JLocationInfoAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public JLocationInfoAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public JLocationInfoAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JLocationInfoRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Message; import org.jdiameter.api.cxdx.events.JLocationInfoRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JLocationInfoRequestImpl extends AppRequestEventImpl implements JLocationInfoRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JLocationInfoRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JMultimediaAuthAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.cxdx.events.JMultimediaAuthAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JMultimediaAuthAnswerImpl extends AppAnswerEventImpl implements JMultimediaAuthAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JMultimediaAuthAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public JMultimediaAuthAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public JMultimediaAuthAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public JMultimediaAuthAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JMultimediaAuthRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Message; import org.jdiameter.api.cxdx.events.JMultimediaAuthRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JMultimediaAuthRequestImpl extends AppRequestEventImpl implements JMultimediaAuthRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JMultimediaAuthRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JPushProfileAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.cxdx.events.JPushProfileAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JPushProfileAnswerImpl extends AppAnswerEventImpl implements JPushProfileAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JPushProfileAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public JPushProfileAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public JPushProfileAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public JPushProfileAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JPushProfileRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Message; import org.jdiameter.api.cxdx.events.JPushProfileRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JPushProfileRequestImpl extends AppRequestEventImpl implements JPushProfileRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JPushProfileRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JRegistrationTerminationAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.cxdx.events.JRegistrationTerminationAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JRegistrationTerminationAnswerImpl extends AppAnswerEventImpl implements JRegistrationTerminationAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JRegistrationTerminationAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public JRegistrationTerminationAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public JRegistrationTerminationAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public JRegistrationTerminationAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JRegistrationTerminationRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Message; import org.jdiameter.api.cxdx.events.JRegistrationTerminationRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JRegistrationTerminationRequestImpl extends AppRequestEventImpl implements JRegistrationTerminationRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JRegistrationTerminationRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JServerAssignmentAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.cxdx.events.JServerAssignmentAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JServerAssignmentAnswerImpl extends AppAnswerEventImpl implements JServerAssignmentAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JServerAssignmentAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public JServerAssignmentAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public JServerAssignmentAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public JServerAssignmentAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JServerAssignmentRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Message; import org.jdiameter.api.cxdx.events.JServerAssignmentRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JServerAssignmentRequestImpl extends AppRequestEventImpl implements JServerAssignmentRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JServerAssignmentRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JUserAuthorizationAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.cxdx.events.JUserAuthorizationAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JUserAuthorizationAnswerImpl extends AppAnswerEventImpl implements JUserAuthorizationAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JUserAuthorizationAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public JUserAuthorizationAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public JUserAuthorizationAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public JUserAuthorizationAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/cxdx/JUserAuthorizationRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.cxdx; import org.jdiameter.api.Message; import org.jdiameter.api.cxdx.events.JUserAuthorizationRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JUserAuthorizationRequestImpl extends AppRequestEventImpl implements JUserAuthorizationRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JUserAuthorizationRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/gq/GqSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.gq; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.auth.ClientAuthSession; import org.jdiameter.api.auth.ClientAuthSessionListener; import org.jdiameter.api.auth.ServerAuthSession; import org.jdiameter.api.auth.ServerAuthSessionListener; import org.jdiameter.api.auth.events.AbortSessionAnswer; import org.jdiameter.api.auth.events.AbortSessionRequest; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.auth.events.SessionTermAnswer; import org.jdiameter.api.auth.events.SessionTermRequest; import org.jdiameter.api.gq.GqClientSession; import org.jdiameter.api.gq.GqServerSession; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.auth.IClientAuthSessionData; import org.jdiameter.client.impl.app.gq.GqClientSessionImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.auth.IAuthMessageFactory; import org.jdiameter.common.api.app.auth.IAuthSessionData; import org.jdiameter.common.api.app.auth.IAuthSessionFactory; import org.jdiameter.common.api.app.auth.IClientAuthActionContext; import org.jdiameter.common.api.app.auth.IServerAuthActionContext; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.server.impl.app.auth.IServerAuthSessionData; import org.jdiameter.server.impl.app.gq.GqServerSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default Diameter Gq Application Session Factory implementation * * @author Yulian Oifa * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class GqSessionFactoryImpl implements IAuthSessionFactory, IAuthMessageFactory, ServerAuthSessionListener, ClientAuthSessionListener, IClientAuthActionContext, IServerAuthActionContext, StateChangeListener { private static final long authAppId = 16777222L; protected IAuthMessageFactory messageFactory; protected ServerAuthSessionListener serverSessionListener; protected StateChangeListener stateListener; protected ClientAuthSessionListener clientSessionListener; protected boolean stateles; protected long messageTimeout = 5000; protected static final Logger logger = LoggerFactory.getLogger(GqSessionFactoryImpl.class); protected ISessionDatasource iss; protected ISessionFactory sessionFactory = null; protected IServerAuthActionContext serverSessionContext; protected IClientAuthActionContext clientSessionContext; protected IAppSessionDataFactory sessionDataFactory; public GqSessionFactoryImpl(SessionFactory sessionFactory) { super(); this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IAuthSessionData.class); } /** * @return the clientSessionContext */ @Override public IClientAuthActionContext getClientSessionContext() { return clientSessionContext != null ? clientSessionContext : this; } /** * @param clientSessionContext the clientSessionContext to set */ @Override public void setClientSessionContext(IClientAuthActionContext clientSessionContext) { this.clientSessionContext = clientSessionContext; } /** * @return the serverSessionContext */ @Override public IServerAuthActionContext getServerSessionContext() { return serverSessionContext != null ? serverSessionContext : this; } /** * @param serverSessionContext the serverSessionContext to set */ @Override public void setServerSessionContext(IServerAuthActionContext serverSessionContext) { this.serverSessionContext = serverSessionContext; } /** * @return the messageTimeout */ @Override public long getMessageTimeout() { return messageTimeout; } /** * @param messageTimeout the messageTimeout to set */ @Override public void setMessageTimeout(long messageTimeout) { this.messageTimeout = messageTimeout; } /** * @return the messageFactory */ @Override public IAuthMessageFactory getMessageFactory() { return messageFactory != null ? messageFactory : this; } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(IAuthMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @return the serverSessionListener */ @Override public ServerAuthSessionListener getServerSessionListener() { return serverSessionListener != null ? serverSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerAuthSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { return stateListener != null ? stateListener : this; } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } /** * @return the clientSessionListener */ @Override public ClientAuthSessionListener getClientSessionListener() { return clientSessionListener != null ? clientSessionListener : this; } /** * @param clientSessionListener the clientSessionListener to set */ @Override public void setClientSessionListener(ClientAuthSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } @Override public boolean isStateles() { return stateles; } @Override public void setStateles(boolean stateles) { this.stateles = stateles; } @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } try { if (aClass == GqServerSession.class) { IServerAuthSessionData sessionData = (IServerAuthSessionData) this.sessionDataFactory .getAppSessionData(GqServerSession.class, sessionId); GqServerSessionImpl session = new GqServerSessionImpl(sessionData, sessionFactory, getServerSessionListener(), getMessageFactory(), getStateListener(), getServerSessionContext(), messageTimeout, isStateles()); session.getSessions().get(0).setRequestListener(session); return session; } else { if (aClass == GqClientSession.class) { IClientAuthSessionData sessionData = (IClientAuthSessionData) this.sessionDataFactory .getAppSessionData(GqClientSession.class, sessionId); GqClientSessionImpl session = new GqClientSessionImpl(sessionData, sessionFactory, getClientSessionListener(), getMessageFactory(), getStateListener(), getClientSessionContext(), isStateles()); session.getSessions().get(0).setRequestListener(session); return session; } } } catch (Exception e) { logger.error("Failure trying to obtain new authorization session", e); } return null; } @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { try { if (aClass == GqServerSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerAuthSessionData sessionData = (IServerAuthSessionData) this.sessionDataFactory .getAppSessionData(ServerAuthSession.class, sessionId); sessionData.setApplicationId(applicationId); GqServerSessionImpl session = new GqServerSessionImpl(sessionData, sessionFactory, getServerSessionListener(), getMessageFactory(), getStateListener(), getServerSessionContext(), messageTimeout, isStateles()); iss.addSession(session); session.getSessions().get(0).setRequestListener(session); return session; } else { if (aClass == GqClientSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientAuthSessionData sessionData = (IClientAuthSessionData) this.sessionDataFactory .getAppSessionData(ClientAuthSession.class, sessionId); sessionData.setApplicationId(applicationId); GqClientSessionImpl session = new GqClientSessionImpl(sessionData, sessionFactory, getClientSessionListener(), getMessageFactory(), getStateListener(), getClientSessionContext(), isStateles()); iss.addSession(session); // iss.setSessionListener(clientSession.getSessionId(), (NetworkReqListener) appSession); session.getSessions().get(0).setRequestListener(session); return session; } } } catch (Exception e) { logger.error("Failure trying to obtain new authorization session", e); } return null; } // Message Factory Methods ------------------------------------------------ @Override public AppAnswerEvent createAuthAnswer(Answer answer) { return new AppAnswerEventImpl(answer); } @Override public AppRequestEvent createAuthRequest(Request request) { return new AppRequestEventImpl(request); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.auth.IAuthMessageFactory#getAuthMessageCommandCode() */ @Override public int getAuthMessageCommandCode() { return 265; } @Override public ApplicationId getApplicationId() { return ApplicationId.createByAuthAppId(authAppId); } // Message Handlers ------------------------------------------------------- /* * (non-Javadoc) * * @see org.jdiameter.api.auth.ClientAuthSessionListener# * doAbortSessionRequestEvent(org.jdiameter.api.auth.ClientAuthSession, org.jdiameter.api.auth.events.AbortSessionRequest) */ @Override public void doAbortSessionRequestEvent(ClientAuthSession appSession, AbortSessionRequest asr) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Gq AuthorizationSessionFactory :: doAbortSessionRequestEvent :: appSession[{}], ASR[{}]", appSession, asr); } /* * (non-Javadoc) * * @see org.jdiameter.api.auth.ServerAuthSessionListener# * doAbortSessionAnswerEvent(org.jdiameter.api.auth.ServerAuthSession, org.jdiameter.api.auth.events.AbortSessionAnswer) */ @Override public void doAbortSessionAnswerEvent(ServerAuthSession appSession, AbortSessionAnswer asa) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Gq AuthorizationSessionFactory :: doAbortSessionAnswerEvent :: appSession[{}], ASA[{}]", appSession, asa); } /* * (non-Javadoc) * * @see org.jdiameter.api.auth.ServerAuthSessionListener# * doSessionTerminationRequestEvent(org.jdiameter.api.auth.ServerAuthSession, * org.jdiameter.api.auth.events.SessionTermRequest) */ @Override public void doSessionTerminationRequestEvent(ServerAuthSession appSession, SessionTermRequest str) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Gq AuthorizationSessionFactory :: doSessionTerminationRequestEvent :: appSession[{}], STR[{}]", appSession, str); } /* * (non-Javadoc) * * @see org.jdiameter.api.auth.ClientAuthSessionListener# * doSessionTerminationAnswerEvent(org.jdiameter.api.auth.ClientAuthSession, * org.jdiameter.api.auth.events.SessionTermAnswer) */ @Override public void doSessionTerminationAnswerEvent(ClientAuthSession appSession, SessionTermAnswer sta) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Gq AuthorizationSessionFactory :: doSessionTerminationAnswerEvent :: appSession[{}], STA[{}]", appSession, sta); } /* * (non-Javadoc) * * @see org.jdiameter.api.auth.ServerAuthSessionListener#doAuthRequestEvent(org.jdiameter.api.auth.ServerAuthSession, * org.jdiameter.api.app.AppRequestEvent) */ @Override public void doAuthRequestEvent(ServerAuthSession appSession, AppRequestEvent request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Gq AuthorizationSessionFactory :: doAuthRequestEvent :: appSession[{}], Request[{}]", appSession, request); } /* * (non-Javadoc) * * @see org.jdiameter.api.auth.ClientAuthSessionListener# * doAuthAnswerEvent(org.jdiameter.api.auth.ClientAuthSession, org.jdiameter.api.app.AppRequestEvent, * org.jdiameter.api.app.AppAnswerEvent) */ @Override public void doAuthAnswerEvent(ClientAuthSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Gq AuthorizationSessionFactory :: doAuthAnswerEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } /* * (non-Javadoc) * * @see org.jdiameter.api.auth.ClientAuthSessionListener# * doReAuthRequestEvent(org.jdiameter.api.auth.ClientAuthSession, org.jdiameter.api.auth.events.ReAuthRequest) */ @Override public void doReAuthRequestEvent(ClientAuthSession appSession, ReAuthRequest rar) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Gq AuthorizationSessionFactory :: doReAuthRequestEvent :: appSession[{}], RAR[{}]", appSession, rar); } /* * (non-Javadoc) * * @see org.jdiameter.api.auth.ServerAuthSessionListener# * doReAuthAnswerEvent(org.jdiameter.api.auth.ServerAuthSession, org.jdiameter.api.auth.events.ReAuthRequest, * org.jdiameter.api.auth.events.ReAuthAnswer) */ @Override public void doReAuthAnswerEvent(ServerAuthSession appSession, ReAuthRequest rar, ReAuthAnswer raa) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Gq AuthorizationSessionFactory :: doReAuthAnswerEvent :: appSession[{}], RAR[{}], RAA[{}]", new Object[] { appSession, rar, raa }); } /* * (non-Javadoc) * * @see org.jdiameter.api.auth.ServerAuthSessionListener# * doOtherEvent(org.jdiameter.api.app.AppSession, org.jdiameter.api.app.AppRequestEvent, * org.jdiameter.api.app.AppAnswerEvent) */ @Override public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Gq AuthorizationSessionFactory :: doOtherEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } // State Change Listener -------------------------------------------------- /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Enum, java.lang.Enum) */ @Override public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter Gq AuthorizationSessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter Gq AuthorizationSessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } // Context Methods -------------------------------------------------------- /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.auth.IClientAuthActionContext#accessTimeoutElapses(org.jdiameter.api.auth.ClientAuthSession) */ @Override public void accessTimeoutElapses(ClientAuthSession session) throws InternalException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.auth.IClientAuthActionContext#getAccessTimeout() */ @Override public long getAccessTimeout() throws InternalException { return 20000; } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.auth.IClientAuthActionContext#disconnectUserOrDev(org.jdiameter.api.auth.ClientAuthSession, * org.jdiameter.api.Message) */ @Override public void disconnectUserOrDev(ClientAuthSession session, Message request) throws InternalException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.auth.IServerAuthActionContext#accessTimeoutElapses(org.jdiameter.api.auth.ServerAuthSession) */ @Override public void accessTimeoutElapses(ServerAuthSession session) throws InternalException { // TODO Auto-generated method stub } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/gx/AppGxSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.gx; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.gx.IGxSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public abstract class AppGxSessionImpl extends AppSessionImpl implements NetworkReqListener, StateMachine { protected Lock sendAndStateLock = new ReentrantLock(); //FIXME: those must be recreated from local resources! //FIXME: change this to single ref! protected transient List stateListeners = new CopyOnWriteArrayList(); public AppGxSessionImpl(ISessionFactory sf, IGxSessionData sessionData) { super(sf, sessionData); } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } @Override public void release() { //stateListeners.clear(); super.release(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/gx/GxCreditControlAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.gx; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.gx.events.GxCreditControlAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Carl-Magnus Björkell * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class GxCreditControlAnswerImpl extends AppAnswerEventImpl implements GxCreditControlAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(GxCreditControlAnswerImpl.class); private static final int CREDIT_CONTROL_FAILURE_HANDLING_AVP_CODE = 427; private static final int DIRECT_DEBITING_FAILURE_HANDLING_AVP_CODE = 428; private static final int REQUESTED_ACTION_AVP_CODE = 436; private static final int CC_REQUEST_TYPE_AVP_CODE = 416; private static final int VALIDITY_TIME_AVP_CODE = 448; /** * @param answer */ public GxCreditControlAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public GxCreditControlAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public GxCreditControlAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public GxCreditControlAnswerImpl(Request request) { super(request); } @Override public boolean isCreditControlFailureHandlingAVPPresent() { return super.message.getAvps().getAvp(CREDIT_CONTROL_FAILURE_HANDLING_AVP_CODE) != null; } @Override public int getCredidControlFailureHandlingAVPValue() { Avp credidControlFailureHandlingAvp = super.message.getAvps().getAvp(CREDIT_CONTROL_FAILURE_HANDLING_AVP_CODE); if (credidControlFailureHandlingAvp != null) { try { return credidControlFailureHandlingAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e); } } return -1; } @Override public boolean isDirectDebitingFailureHandlingAVPPresent() { return super.message.getAvps().getAvp(DIRECT_DEBITING_FAILURE_HANDLING_AVP_CODE) != null; } @Override public int getDirectDebitingFailureHandlingAVPValue() { Avp directDebitingFailureHandlingAvp = super.message.getAvps().getAvp(DIRECT_DEBITING_FAILURE_HANDLING_AVP_CODE); if (directDebitingFailureHandlingAvp != null) { try { return directDebitingFailureHandlingAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Direct-Debiting-Failure-Handling AVP value", e); } } return -1; } @Override public Avp getValidityTimeAvp() { return super.message.getAvps().getAvp(VALIDITY_TIME_AVP_CODE); } @Override public boolean isRequestTypeAVPPresent() { return super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE) != null; } @Override public int getRequestTypeAVPValue() { Avp requestTypeAvp = super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE); if (requestTypeAvp != null) { try { return requestTypeAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain CC-Request-Type AVP value", e); } } return -1; } public boolean isRequestedActionAVPPresent() { return super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE) != null; } public int getRequestedActionAVPValue() { Avp requestedActionAvp = super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE); if (requestedActionAvp != null) { try { return requestedActionAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Requested-Action AVP value", e); } } return -1; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/gx/GxCreditControlRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.gx; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.gx.events.GxCreditControlRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public class GxCreditControlRequestImpl extends AppRequestEventImpl implements GxCreditControlRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(GxCreditControlRequestImpl.class); private static final int REQUESTED_ACTION_AVP_CODE = 436; private static final int CC_REQUEST_TYPE_AVP_CODE = 416; public GxCreditControlRequestImpl(AppSession session, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); } public GxCreditControlRequestImpl(Request request) { super(request); } @Override public boolean isRequestedActionAVPPresent() { return super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE) != null; } @Override public int getRequestedActionAVPValue() { Avp requestedActionAvp = super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE); if (requestedActionAvp != null) { try { return requestedActionAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Requested-Action AVP value", e); } } return -1; } @Override public boolean isRequestTypeAVPPresent() { return super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE) != null; } @Override public int getRequestTypeAVPValue() { Avp requestTypeAvp = super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE); if (requestTypeAvp != null) { try { return requestTypeAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain CC-Request-Type AVP value", e); } } return -1; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/gx/GxLocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.gx; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.gx.ClientGxSession; import org.jdiameter.api.gx.ServerGxSession; import org.jdiameter.client.impl.app.gx.ClientGxSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.gx.IGxSessionData; import org.jdiameter.server.impl.app.gx.ServerGxSessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class GxLocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IGxSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientGxSession.class)) { ClientGxSessionDataLocalImpl data = new ClientGxSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerGxSession.class)) { ServerGxSessionDataLocalImpl data = new ServerGxSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } throw new IllegalArgumentException(clazz.toString()); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/gx/GxReAuthAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.gx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.gx.events.GxReAuthAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public class GxReAuthAnswerImpl extends AppAnswerEventImpl implements GxReAuthAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(GxReAuthAnswerImpl.class); public GxReAuthAnswerImpl(Request message, long resultCode) { super(message.createAnswer(resultCode)); } public GxReAuthAnswerImpl(Answer message) { super(message); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/gx/GxReAuthRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.gx; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.gx.events.GxReAuthRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public class GxReAuthRequestImpl extends AppRequestEventImpl implements GxReAuthRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(GxReAuthRequestImpl.class); public GxReAuthRequestImpl(AppSession session, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); } public GxReAuthRequestImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/gx/GxSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.gx; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.Request; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.gx.ClientGxSession; import org.jdiameter.api.gx.ClientGxSessionListener; import org.jdiameter.api.gx.ServerGxSession; import org.jdiameter.api.gx.ServerGxSessionListener; import org.jdiameter.api.gx.events.GxCreditControlAnswer; import org.jdiameter.api.gx.events.GxCreditControlRequest; import org.jdiameter.api.gx.events.GxReAuthAnswer; import org.jdiameter.api.gx.events.GxReAuthRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.gx.ClientGxSessionImpl; import org.jdiameter.client.impl.app.gx.IClientGxSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.gx.IClientGxSessionContext; import org.jdiameter.common.api.app.gx.IGxMessageFactory; import org.jdiameter.common.api.app.gx.IGxSessionData; import org.jdiameter.common.api.app.gx.IGxSessionFactory; import org.jdiameter.common.api.app.gx.IServerGxSessionContext; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.gx.IServerGxSessionData; import org.jdiameter.server.impl.app.gx.ServerGxSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default Diameter Gx Session Factory implementation. * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public class GxSessionFactoryImpl implements IGxSessionFactory, ClientGxSessionListener, ServerGxSessionListener, StateChangeListener, IGxMessageFactory, IServerGxSessionContext, IClientGxSessionContext { // Message timeout value (in milliseconds) protected int defaultDirectDebitingFailureHandling = 0; protected int defaultCreditControlFailureHandling = 0; // its seconds protected long defaultValidityTime = 60; protected long defaultTxTimerValue = 30; // local not replicated listeners: protected ClientGxSessionListener clientSessionListener; protected ServerGxSessionListener serverSessionListener; protected StateChangeListener stateListener; protected IServerGxSessionContext serverContextListener; protected IClientGxSessionContext clientContextListener; protected IGxMessageFactory messageFactory; protected static final Logger logger = LoggerFactory.getLogger(GxSessionFactoryImpl.class); protected ISessionDatasource iss; protected ISessionFactory sessionFactory = null; protected IAppSessionDataFactory sessionDataFactory; public GxSessionFactoryImpl(SessionFactory sessionFactory) { super(); this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IGxSessionData.class); } public GxSessionFactoryImpl(SessionFactory sessionFactory, int defaultDirectDebitingFailureHandling, int defaultCreditControlFailureHandling, long defaultValidityTime, long defaultTxTimerValue) { this(sessionFactory); this.defaultDirectDebitingFailureHandling = defaultDirectDebitingFailureHandling; this.defaultCreditControlFailureHandling = defaultCreditControlFailureHandling; this.defaultValidityTime = defaultValidityTime; this.defaultTxTimerValue = defaultTxTimerValue; } /** * @return the clientSessionListener */ @Override public ClientGxSessionListener getClientSessionListener() { return clientSessionListener != null ? clientSessionListener : this; } /** * @param clientSessionListener the clientSessionListener to set */ @Override public void setClientSessionListener(final ClientGxSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the serverSessionListener */ @Override public ServerGxSessionListener getServerSessionListener() { return serverSessionListener != null ? serverSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerGxSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the serverContextListener */ @Override public IServerGxSessionContext getServerContextListener() { return serverContextListener != null ? serverContextListener : this; } /** * @param serverContextListener the serverContextListener to set */ @Override public void setServerContextListener(IServerGxSessionContext serverContextListener) { this.serverContextListener = serverContextListener; } /** * @return the clientContextListener */ @Override public IClientGxSessionContext getClientContextListener() { return clientContextListener != null ? clientContextListener : this; } /** * @return the messageFactory */ @Override public IGxMessageFactory getMessageFactory() { return messageFactory != null ? messageFactory : this; } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(final IGxMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @param clientContextListener the clientContextListener to set */ @Override public void setClientContextListener(IClientGxSessionContext clientContextListener) { this.clientContextListener = clientContextListener; } /** * @return the sessionFactory */ public SessionFactory getSessionFactory() { return sessionFactory; } /** * @param sessionFactory the sessionFactory to set */ public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = (ISessionFactory) sessionFactory; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { return stateListener != null ? stateListener : this; } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ClientGxSession.class) { IClientGxSessionData sessionData = (IClientGxSessionData) this.sessionDataFactory .getAppSessionData(ClientGxSession.class, sessionId); ClientGxSessionImpl clientSession = new ClientGxSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerGxSession.class) { IServerGxSessionData sessionData = (IServerGxSessionData) this.sessionDataFactory .getAppSessionData(ServerGxSession.class, sessionId); ServerGxSessionImpl serverSession = new ServerGxSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getServerSessionListener(), this.getServerContextListener(), this.getStateListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientGxSession.class + "," + ServerGxSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Gx Session.", e); } return appSession; } @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; try { // FIXME: if (aClass == ClientGxSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientGxSessionData sessionData = (IClientGxSessionData) this.sessionDataFactory .getAppSessionData(ClientGxSession.class, sessionId); sessionData.setApplicationId(applicationId); ClientGxSessionImpl clientSession = new ClientGxSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); // this goes first! iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerGxSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerGxSessionData sessionData = (IServerGxSessionData) this.sessionDataFactory .getAppSessionData(ServerGxSession.class, sessionId); sessionData.setApplicationId(applicationId); ServerGxSessionImpl serverSession = new ServerGxSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getServerSessionListener(), this.getServerContextListener(), this.getStateListener()); iss.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientGxSession.class + "," + ServerGxSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Gx Session.", e); } return appSession; } // Default implementation of methods so there are no exception! // Message Handlers -------------------------------------------------------- @Override public void doCreditControlRequest(ServerGxSession session, GxCreditControlRequest request) throws InternalException { } @Override public void doCreditControlAnswer(ClientGxSession session, GxCreditControlRequest request, GxCreditControlAnswer answer) throws InternalException { } @Override public void doGxReAuthRequest(ClientGxSession session, GxReAuthRequest request) throws InternalException { } @Override public void doGxReAuthAnswer(ServerGxSession session, GxReAuthRequest request, GxReAuthAnswer answer) throws InternalException { } @Override public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { } // Message Factory Methods ------------------------------------------------- @Override public GxCreditControlAnswer createCreditControlAnswer(Answer answer) { return new GxCreditControlAnswerImpl(answer); } @Override public GxCreditControlRequest createCreditControlRequest(Request req) { return new GxCreditControlRequestImpl(req); } @Override public GxReAuthAnswer createGxReAuthAnswer(Answer answer) { return new GxReAuthAnswerImpl(answer); } @Override public GxReAuthRequest createGxReAuthRequest(Request req) { return new GxReAuthRequestImpl(req); } // Context Methods --------------------------------------------------------- @Override @SuppressWarnings("unchecked") public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter Gx SessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override @SuppressWarnings("unchecked") public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter Gx SessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } // FIXME: add ctx methods proxy calls! @Override public void sessionSupervisionTimerExpired(ServerGxSession session) { // this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session); session.release(); } @Override @SuppressWarnings("unchecked") public void sessionSupervisionTimerReStarted(ServerGxSession session, ScheduledFuture future) { // TODO Complete this method. } @Override @SuppressWarnings("unchecked") public void sessionSupervisionTimerStarted(ServerGxSession session, ScheduledFuture future) { // TODO Complete this method. } @Override @SuppressWarnings("unchecked") public void sessionSupervisionTimerStopped(ServerGxSession session, ScheduledFuture future) { // TODO Complete this method. } @Override public void timeoutExpired(Request request) { // FIXME What should we do when there's a timeout? } @Override public void denyAccessOnDeliverFailure(ClientGxSession clientGxSessionImpl, Message request) { // TODO Complete this method. } @Override public void denyAccessOnFailureMessage(ClientGxSession clientGxSessionImpl) { // TODO Complete this method. } @Override public void denyAccessOnTxExpire(ClientGxSession clientGxSessionImpl) { // this.resourceAdaptor.sessionDestroyed(clientGxSessionImpl.getSessions().get(0).getSessionId(), // clientGxSessionImpl); clientGxSessionImpl.release(); } @Override public int getDefaultCCFHValue() { return defaultCreditControlFailureHandling; } @Override public int getDefaultDDFHValue() { return defaultDirectDebitingFailureHandling; } @Override public long getDefaultTxTimerValue() { return defaultTxTimerValue; } @Override public void grantAccessOnDeliverFailure(ClientGxSession clientGxSessionImpl, Message request) { // TODO Auto-generated method stub } @Override public void grantAccessOnFailureMessage(ClientGxSession clientGxSessionImpl) { // TODO Auto-generated method stub } @Override public void grantAccessOnTxExpire(ClientGxSession clientGxSessionImpl) { // TODO Auto-generated method stub } @Override public void indicateServiceError(ClientGxSession clientGxSessionImpl) { // TODO Auto-generated method stub } @Override public void txTimerExpired(ClientGxSession session) { // this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session); session.release(); } @Override public long[] getApplicationIds() { // FIXME: What should we do here? return new long[] { 16777238, 16777238 }; } @Override public long getDefaultValidityTime() { return this.defaultValidityTime; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rf/AppRfSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.rf; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.Request; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.rf.events.RfAccountingAnswer; import org.jdiameter.api.rf.events.RfAccountingRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.rf.IRfSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public abstract class AppRfSessionImpl extends AppSessionImpl implements NetworkReqListener, org.jdiameter.api.app.StateMachine { protected Lock sendAndStateLock = new ReentrantLock(); protected ApplicationId appId; protected transient List stateListeners = new CopyOnWriteArrayList(); public AppRfSessionImpl(ISessionFactory sf, IRfSessionData sessionData) { super(sf, sessionData); } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } protected RfAccountingRequest createAccountRequest(Request request) { return new RfAccountingRequestImpl(request); } protected RfAccountingAnswer createAccountAnswer(Answer answer) { return new RfAccountingAnswerImpl(answer); } @Override public void release() { //stateListeners.clear(); super.release(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rf/RfAccountingAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.rf; import static org.jdiameter.api.Avp.ACC_RECORD_NUMBER; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.rf.events.RfAccountingAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RfAccountingAnswerImpl extends AppAnswerEventImpl implements RfAccountingAnswer { private static final long serialVersionUID = 1L; /** * @param request * @param vendorId * @param resultCode */ public RfAccountingAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public RfAccountingAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public RfAccountingAnswerImpl(Request request) { super(request); } public RfAccountingAnswerImpl(Request request, int accountRecordType, int accReqNumber, long resultCode) { super(request.createAnswer(resultCode)); try { getMessage().getAvps().addAvp(Avp.ACC_RECORD_TYPE, accountRecordType); getMessage().getAvps().addAvp(Avp.ACC_RECORD_NUMBER, accReqNumber); } catch (Exception e) { throw new IllegalArgumentException(e); } } public RfAccountingAnswerImpl(Answer answer) { super(answer); } @Override public int getAccountingRecordType() throws AvpDataException { Avp accRecordTypeAvp = message.getAvps().getAvp(Avp.ACC_RECORD_TYPE); if (accRecordTypeAvp != null) { return accRecordTypeAvp.getInteger32(); } else { throw new AvpDataException("Avp ACC_RECORD_TYPE not found"); } } @Override public long getAccountingRecordNumber() throws AvpDataException { Avp accRecordNumberAvp = message.getAvps().getAvp(ACC_RECORD_NUMBER); if (accRecordNumberAvp != null) { return accRecordNumberAvp.getUnsigned32(); } else { throw new AvpDataException("Avp ACC_RECORD_NUMBER not found"); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rf/RfAccountingRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.rf; import static org.jdiameter.api.Avp.ACC_RECORD_NUMBER; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rf.events.RfAccountingRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RfAccountingRequestImpl extends AppRequestEventImpl implements RfAccountingRequest { private static final long serialVersionUID = 1L; public RfAccountingRequestImpl(AppSession session, int accountRecordType, int accReqNumber, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); try { getMessage().getAvps().addAvp(Avp.ACC_RECORD_TYPE, accountRecordType); getMessage().getAvps().addAvp(Avp.ACC_RECORD_NUMBER, accReqNumber); } catch (Exception e) { throw new IllegalArgumentException(e); } } public RfAccountingRequestImpl(Request request) { super(request); } @Override public int getAccountingRecordType() throws AvpDataException { Avp accRecordTypeAvp = message.getAvps().getAvp(Avp.ACC_RECORD_TYPE); if (accRecordTypeAvp != null) { return accRecordTypeAvp.getInteger32(); } else { throw new AvpDataException("Avp ACC_RECORD_TYPE not found"); } } @Override public long getAccountingRecordNumber() throws AvpDataException { Avp accRecordNumberAvp = message.getAvps().getAvp(ACC_RECORD_NUMBER); if (accRecordNumberAvp != null) { return accRecordNumberAvp.getUnsigned32(); } else { throw new AvpDataException("Avp ACC_RECORD_NUMBER not found"); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rf/RfLocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.rf; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rf.ClientRfSession; import org.jdiameter.api.rf.ServerRfSession; import org.jdiameter.client.impl.app.rf.ClientRfSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.rf.IRfSessionData; import org.jdiameter.server.impl.app.rf.ServerRfSessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class RfLocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IRfSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientRfSession.class)) { ClientRfSessionDataLocalImpl data = new ClientRfSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerRfSession.class)) { ServerRfSessionDataLocalImpl data = new ServerRfSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } throw new IllegalArgumentException(clazz.toString()); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rf/RfSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rf; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.rf.ClientRfSession; import org.jdiameter.api.rf.ClientRfSessionListener; import org.jdiameter.api.rf.ServerRfSession; import org.jdiameter.api.rf.ServerRfSessionListener; import org.jdiameter.api.rf.events.RfAccountingAnswer; import org.jdiameter.api.rf.events.RfAccountingRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.rf.ClientRfSessionImpl; import org.jdiameter.client.impl.app.rf.IClientRfSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.rf.IClientRfActionContext; import org.jdiameter.common.api.app.rf.IRfSessionData; import org.jdiameter.common.api.app.rf.IRfSessionFactory; import org.jdiameter.common.api.app.rf.IServerRfActionContext; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.rf.IServerRfSessionData; import org.jdiameter.server.impl.app.rf.ServerRfSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default Diameter Rf Session Factory implementation * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class RfSessionFactoryImpl implements IRfSessionFactory, ServerRfSessionListener, ClientRfSessionListener, IClientRfActionContext, IServerRfActionContext, StateChangeListener { protected static final Logger logger = LoggerFactory.getLogger(RfSessionFactoryImpl.class); protected ServerRfSessionListener serverSessionListener; protected StateChangeListener stateListener; protected ClientRfSessionListener clientSessionListener; protected IClientRfActionContext clientContextListener; protected IServerRfActionContext serverContextListener; protected ISessionDatasource iss; protected ISessionFactory sessionFactory = null; protected long messageTimeout = 5000; protected ApplicationId applicationId; protected IAppSessionDataFactory sessionDataFactory; protected RfSessionFactoryImpl() { } public RfSessionFactoryImpl(SessionFactory sessionFactory) { super(); this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IRfSessionData.class); } // ACC Factory Methods // ------------------------------------------------------ /** * @return the serverSessionListener */ @Override public ServerRfSessionListener getServerSessionListener() { if (this.serverSessionListener != null) { return serverSessionListener; } else { return this; } } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerRfSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { if (this.stateListener != null) { return stateListener; } else { return this; } } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } /** * @return the clientSessionListener */ @Override public ClientRfSessionListener getClientSessionListener() { if (this.clientSessionListener != null) { return clientSessionListener; } else { return this; } } /** * @param clientSessionListener the clientSessionListener to set */ @Override public void setClientSessionListener(ClientRfSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the clientContextListener */ @Override public IClientRfActionContext getClientContextListener() { if (this.clientContextListener != null) { return clientContextListener; } else { return this; } } /** * @param clientContextListener the clientContextListener to set */ @Override public void setClientContextListener(IClientRfActionContext clientContextListener) { this.clientContextListener = clientContextListener; } /** * @return the serverContextListener */ @Override public IServerRfActionContext getServerContextListener() { if (this.serverContextListener != null) { return serverContextListener; } else { return this; } } /** * @param serverContextListener the serverContextListener to set */ @Override public void setServerContextListener(IServerRfActionContext serverContextListener) { this.serverContextListener = serverContextListener; } /** * @return the messageTimeout */ @Override public long getMessageTimeout() { return messageTimeout; } /** * @param messageTimeout the messageTimeout to set */ @Override public void setMessageTimeout(long messageTimeout) { this.messageTimeout = messageTimeout; } /** * @return the sessionFactory */ public ISessionFactory getSessionFactory() { return sessionFactory; } /** * @param sessionFactory the sessionFactory to set */ public void setSessionFactory(ISessionFactory sessionFactory) { this.sessionFactory = sessionFactory; if (this.iss == null) { this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); } } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.acc.IAccSessionFactory#getApplicationId() */ @Override public ApplicationId getApplicationId() { return this.applicationId; } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.acc.IAccSessionFactory#setApplicationId( * org.jdiameter.api.ApplicationId) */ @Override public void setApplicationId(ApplicationId id) { this.applicationId = id; } // App Session Factory // ------------------------------------------------------ @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ServerRfSession.class) { IServerRfSessionData sessionData = (IServerRfSessionData) this.sessionDataFactory .getAppSessionData(ServerRfSession.class, sessionId); // FIXME: determine how to get boolean flag! ServerRfSessionImpl session = new ServerRfSessionImpl(sessionData, sessionFactory, getServerSessionListener(), getServerContextListener(), getStateListener(), messageTimeout, true); session.getSessions().get(0).setRequestListener(session); appSession = session; } else if (aClass == ClientRfSession.class) { IClientRfSessionData sessionData = (IClientRfSessionData) this.sessionDataFactory .getAppSessionData(ClientRfSession.class, sessionId); ClientRfSessionImpl session = new ClientRfSessionImpl(sessionData, sessionFactory, getClientSessionListener(), getClientContextListener(), getStateListener(), this.getApplicationId()); session.getSessions().get(0).setRequestListener(session); appSession = session; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientRfSession.class + "," + ServerRfSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Rf Session.", e); } return appSession; } @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { try { if (aClass == ServerRfSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerRfSessionData sessionData = (IServerRfSessionData) this.sessionDataFactory .getAppSessionData(ServerRfSession.class, sessionId); sessionData.setApplicationId(applicationId); // FIXME: determine how to get boolean flag! ServerRfSessionImpl session = new ServerRfSessionImpl(sessionData, sessionFactory, getServerSessionListener(), getServerContextListener(), getStateListener(), messageTimeout, true); iss.addSession(session); session.getSessions().get(0).setRequestListener(session); return session; } else if (aClass == ClientRfSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientRfSessionData sessionData = (IClientRfSessionData) this.sessionDataFactory .getAppSessionData(ClientRfSession.class, sessionId); sessionData.setApplicationId(applicationId); ClientRfSessionImpl session = new ClientRfSessionImpl(sessionData, sessionFactory, getClientSessionListener(), getClientContextListener(), getStateListener(), this.getApplicationId()); iss.addSession(session); session.getSessions().get(0).setRequestListener(session); return session; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientRfSession.class + "," + ServerRfSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Rf Session.", e); } return null; } // State Change Listener // ---------------------------------------------------- @Override @SuppressWarnings("unchecked") public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter ACC SessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see * org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, * java.lang.Enum, java.lang.Enum) */ @Override @SuppressWarnings("unchecked") public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter Rf SessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } // /////////////////// // Event listeners // // /////////////////// @Override public void doRfAccountingRequestEvent(ServerRfSession appSession, RfAccountingRequest acr) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info( "Diameter Base RfSessionFactory :: doAccRequestEvent :: appSession[" + appSession + "], Request[" + acr + "]"); } @Override public void doRfAccountingAnswerEvent(ClientRfSession appSession, RfAccountingRequest acr, RfAccountingAnswer aca) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("doRfAnswerEvent :: appSession[" + appSession + "], Request[" + acr + "], Answer[" + aca + "]"); } @Override public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter Base RfountingSessionFactory :: doOtherEvent :: appSession[" + appSession + "], Request[" + request + "], Answer[" + answer + "]"); } // Client context // ----------------------------------------------------------- /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.Rf.IClientRfActionContext#disconnectUserOrDev * (org.jdiameter.api.Request) */ @Override public void disconnectUserOrDev(ClientRfSession appSession, Request sessionTermRequest) throws InternalException { logger.info("disconnectUserOrDev :: appSession[" + appSession + "], Request[" + sessionTermRequest + "]"); } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.Rf.IClientRfActionContext#failedSendRecord * (org.jdiameter.api.Request) */ @Override public boolean failedSendRecord(ClientRfSession appSession, Request rfRequest) throws InternalException { logger.info("failedSendRecord :: appSession[" + appSession + "], Request[" + rfRequest + "]"); return false; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.acc.IClientAccActionContext# * interimIntervalElapses(org.jdiameter.api.Request) */ @Override public void interimIntervalElapses(ClientRfSession appSession, Request interimRequest) throws InternalException { logger.info("interimIntervalElapses :: appSession[" + appSession + "], Request[" + interimRequest + "]"); } // Server context // ----------------------------------------------------------- /* * (non-Javadoc) * * @seeorg.jdiameter.common.api.app.Rf.IServerRfActionContext# * sessionTimeoutElapses(org.jdiameter.api.Rf.ServerRfSession) */ @Override public void sessionTimeoutElapses(ServerRfSession appSession) throws InternalException { logger.info("sessionTimeoutElapses :: appSession[" + appSession + "]"); } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.Rf.IServerRfActionContext#sessionTimerStarted * (org.jdiameter.api.Rf.ServerRfSession, * java.util.concurrent.ScheduledFuture) */ @Override @SuppressWarnings("unchecked") public void sessionTimerStarted(ServerRfSession appSession, ScheduledFuture timer) throws InternalException { logger.info("sessionTimerStarted :: appSession[" + appSession + "]"); } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.app.Rf.IServerRfActionContext#srssionTimerCanceled * (org.jdiameter.api.Rf.ServerRfSession, * java.util.concurrent.ScheduledFuture) */ @Override @SuppressWarnings("unchecked") public void sessionTimerCanceled(ServerRfSession appSession, ScheduledFuture timer) throws InternalException { logger.info("sessionTimerCanceled :: appSession[" + appSession + "]"); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/AppRoSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.ro; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.ro.IRoSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public abstract class AppRoSessionImpl extends AppSessionImpl implements NetworkReqListener, StateMachine { protected Lock sendAndStateLock = new ReentrantLock(); //FIXME: those must be recreated from local resources! //FIXME: change this to single ref! protected transient List stateListeners = new CopyOnWriteArrayList(); public AppRoSessionImpl(ISessionFactory sf, IRoSessionData sessionData) { super(sf, sessionData); } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } @Override public void release() { //stateListeners.clear(); super.release(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoCreditControlAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.ro; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.ro.events.RoCreditControlAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.slf4j.Logger; /** * ... * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class RoCreditControlAnswerImpl extends AppAnswerEventImpl implements RoCreditControlAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = org.slf4j.LoggerFactory.getLogger(RoCreditControlAnswerImpl.class); private static final int CREDIT_CONTROL_FAILURE_HANDLING_AVP_CODE = 427; private static final int DIRECT_DEBITING_FAILURE_HANDLING_AVP_CODE = 428; private static final int REQUESTED_ACTION_AVP_CODE = 436; private static final int CC_REQUEST_TYPE_AVP_CODE = 416; private static final int VALIDITY_TIME_AVP_CODE = 448; /** * @param answer */ public RoCreditControlAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public RoCreditControlAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public RoCreditControlAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public RoCreditControlAnswerImpl(Request request) { super(request); } @Override public boolean isCreditControlFailureHandlingAVPPresent() { return super.message.getAvps().getAvp(CREDIT_CONTROL_FAILURE_HANDLING_AVP_CODE) != null; } @Override public int getCredidControlFailureHandlingAVPValue() { Avp credidControlFailureHandlingAvp = super.message.getAvps().getAvp(CREDIT_CONTROL_FAILURE_HANDLING_AVP_CODE); if (credidControlFailureHandlingAvp != null) { try { return credidControlFailureHandlingAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e); } } return -1; } @Override public boolean isDirectDebitingFailureHandlingAVPPresent() { return super.message.getAvps().getAvp(DIRECT_DEBITING_FAILURE_HANDLING_AVP_CODE) != null; } @Override public int getDirectDebitingFailureHandlingAVPValue() { Avp directDebitingFailureHandlingAvp = super.message.getAvps().getAvp(DIRECT_DEBITING_FAILURE_HANDLING_AVP_CODE); if (directDebitingFailureHandlingAvp != null) { try { return directDebitingFailureHandlingAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Direct-Debiting-Failure-Handling AVP value", e); } } return -1; } @Override public Avp getValidityTimeAvp() { return super.message.getAvps().getAvp(VALIDITY_TIME_AVP_CODE); } @Override public boolean isRequestTypeAVPPresent() { return super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE) != null; } @Override public int getRequestTypeAVPValue() { Avp requestTypeAvp = super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE); if (requestTypeAvp != null) { try { return requestTypeAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain CC-Request-Type AVP value", e); } } return -1; } public boolean isRequestedActionAVPPresent() { return super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE) != null; } public int getRequestedActionAVPValue() { Avp requestedActionAvp = super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE); if (requestedActionAvp != null) { try { return requestedActionAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Requested-Action AVP value", e); } } return -1; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoCreditControlRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.ro; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.ro.events.RoCreditControlRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * ... * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class RoCreditControlRequestImpl extends AppRequestEventImpl implements RoCreditControlRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(RoCreditControlRequestImpl.class); private static final int REQUESTED_ACTION_AVP_CODE = 436; private static final int CC_REQUEST_TYPE_AVP_CODE = 416; public RoCreditControlRequestImpl(AppSession session, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); } public RoCreditControlRequestImpl(Request request) { super(request); } @Override public boolean isRequestedActionAVPPresent() { return super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE) != null; } @Override public int getRequestedActionAVPValue() { Avp requestedActionAvp = super.message.getAvps().getAvp(REQUESTED_ACTION_AVP_CODE); if (requestedActionAvp != null) { try { return requestedActionAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Requested-Action AVP value", e); } } return -1; } @Override public boolean isRequestTypeAVPPresent() { return super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE) != null; } @Override public int getRequestTypeAVPValue() { Avp requestTypeAvp = super.message.getAvps().getAvp(CC_REQUEST_TYPE_AVP_CODE); if (requestTypeAvp != null) { try { return requestTypeAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain CC-Request-Type AVP value", e); } } return -1; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoLocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.ro; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.ro.ClientRoSession; import org.jdiameter.api.ro.ServerRoSession; import org.jdiameter.client.impl.app.ro.ClientRoSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.ro.IRoSessionData; import org.jdiameter.server.impl.app.ro.ServerRoSessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class RoLocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IRoSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientRoSession.class)) { ClientRoSessionDataLocalImpl data = new ClientRoSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerRoSession.class)) { ServerRoSessionDataLocalImpl data = new ServerRoSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } throw new IllegalArgumentException(clazz.toString()); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/ro/RoSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.ro; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.Request; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.ro.ClientRoSession; import org.jdiameter.api.ro.ClientRoSessionListener; import org.jdiameter.api.ro.ServerRoSession; import org.jdiameter.api.ro.ServerRoSessionListener; import org.jdiameter.api.ro.events.RoCreditControlAnswer; import org.jdiameter.api.ro.events.RoCreditControlRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.ro.ClientRoSessionImpl; import org.jdiameter.client.impl.app.ro.IClientRoSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.ro.IClientRoSessionContext; import org.jdiameter.common.api.app.ro.IRoMessageFactory; import org.jdiameter.common.api.app.ro.IRoSessionData; import org.jdiameter.common.api.app.ro.IRoSessionFactory; import org.jdiameter.common.api.app.ro.IServerRoSessionContext; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.auth.ReAuthAnswerImpl; import org.jdiameter.common.impl.app.auth.ReAuthRequestImpl; import org.jdiameter.server.impl.app.ro.IServerRoSessionData; import org.jdiameter.server.impl.app.ro.ServerRoSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default Diameter Ro Session Factory implementation * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RoSessionFactoryImpl implements IRoSessionFactory, ClientRoSessionListener, ServerRoSessionListener, StateChangeListener, IRoMessageFactory, IServerRoSessionContext, IClientRoSessionContext { // Message timeout value (in milliseconds) protected int defaultDirectDebitingFailureHandling = 0; protected int defaultCreditControlFailureHandling = 0; // its seconds protected long defaultValidityTime = 60; protected long defaultTxTimerValue = 30; // local not replicated listeners: protected ClientRoSessionListener clientSessionListener; protected ServerRoSessionListener serverSessionListener; protected StateChangeListener stateListener; protected IServerRoSessionContext serverContextListener; protected IClientRoSessionContext clientContextListener; protected IRoMessageFactory messageFactory; protected static final Logger logger = LoggerFactory.getLogger(RoSessionFactoryImpl.class); protected ISessionDatasource iss; protected IAppSessionDataFactory sessionDataFactory; protected ISessionFactory sessionFactory = null; public RoSessionFactoryImpl(SessionFactory sessionFactory) { super(); this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IRoSessionData.class); } public RoSessionFactoryImpl(SessionFactory sessionFactory, int defaultDirectDebitingFailureHandling, int defaultCreditControlFailureHandling, long defaultValidityTime, long defaultTxTimerValue) { this(sessionFactory); this.defaultDirectDebitingFailureHandling = defaultDirectDebitingFailureHandling; this.defaultCreditControlFailureHandling = defaultCreditControlFailureHandling; this.defaultValidityTime = defaultValidityTime; this.defaultTxTimerValue = defaultTxTimerValue; } /** * @return the clientSessionListener */ @Override public ClientRoSessionListener getClientSessionListener() { if (clientSessionListener != null) { return clientSessionListener; } else { return this; } } /** * @param clientSessionListener the clientSessionListener to set */ @Override public void setClientSessionListener(ClientRoSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the serverSessionListener */ @Override public ServerRoSessionListener getServerSessionListener() { if (serverSessionListener != null) { return serverSessionListener; } else { return this; } } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerRoSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the serverContextListener */ @Override public IServerRoSessionContext getServerContextListener() { if (serverContextListener != null) { return serverContextListener; } else { return this; } } /** * @param serverContextListener the serverContextListener to set */ @Override public void setServerContextListener(IServerRoSessionContext serverContextListener) { this.serverContextListener = serverContextListener; } /** * @return the clientContextListener */ @Override public IClientRoSessionContext getClientContextListener() { if (clientContextListener != null) { return clientContextListener; } else { return this; } } /** * @return the messageFactory */ @Override public IRoMessageFactory getMessageFactory() { if (messageFactory != null) { return messageFactory; } else { return this; } } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(IRoMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @param clientContextListener the clientContextListener to set */ @Override public void setClientContextListener(IClientRoSessionContext clientContextListener) { this.clientContextListener = clientContextListener; } /** * @return the sessionFactory */ public SessionFactory getSessionFactory() { return sessionFactory; } /** * @param sessionFactory the sessionFactory to set */ public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = (ISessionFactory) sessionFactory; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { if (this.stateListener != null) { return stateListener; } else { return this; } } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; try { //TODO:check for existence if (aClass == ClientRoSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } ClientRoSessionImpl clientSession = null; IClientRoSessionData sessionData = (IClientRoSessionData) this.sessionDataFactory .getAppSessionData(ClientRoSession.class, sessionId); sessionData.setApplicationId(applicationId); clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); // this goes first! iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerRoSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerRoSessionData sessionData = (IServerRoSessionData) this.sessionDataFactory .getAppSessionData(ServerRoSession.class, sessionId); sessionData.setApplicationId(applicationId); ServerRoSessionImpl serverSession = new ServerRoSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getServerSessionListener(), this.getServerContextListener(), this.getStateListener()); iss.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientRoSession.class + "," + ServerRoSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Ro Session.", e); } return appSession; } @Override public AppSession getSession(String sessionId, Class aClass) { AppSession appSession = null; if (sessionId == null) { throw new IllegalArgumentException("Session-Id must not be null"); } if (!this.iss.exists(sessionId)) { return null; } try { if (aClass == ClientRoSession.class) { IClientRoSessionData sessionData = (IClientRoSessionData) this.sessionDataFactory .getAppSessionData(ClientRoSession.class, sessionId); ClientRoSessionImpl clientSession = new ClientRoSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); // this goes first! clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerRoSession.class) { IServerRoSessionData sessionData = (IServerRoSessionData) this.sessionDataFactory .getAppSessionData(ServerRoSession.class, sessionId); ServerRoSessionImpl serverSession = new ServerRoSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getServerSessionListener(), this.getServerContextListener(), this.getStateListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientRoSession.class + "," + ServerRoSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Credit-Control Session.", e); } return appSession; } // Message Handlers --------------------------------------------------------- @Override public void doCreditControlRequest(ServerRoSession session, RoCreditControlRequest request) throws InternalException { } @Override public void doCreditControlAnswer(ClientRoSession session, RoCreditControlRequest request, RoCreditControlAnswer answer) throws InternalException { } @Override public void doReAuthRequest(ClientRoSession session, ReAuthRequest request) throws InternalException { } @Override public void doReAuthAnswer(ServerRoSession session, ReAuthRequest request, ReAuthAnswer answer) throws InternalException { } @Override public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { } // Message Factory Methods -------------------------------------------------- @Override public RoCreditControlAnswer createCreditControlAnswer(Answer answer) { return new RoCreditControlAnswerImpl(answer); } @Override public RoCreditControlRequest createCreditControlRequest(Request req) { return new RoCreditControlRequestImpl(req); } @Override public ReAuthAnswer createReAuthAnswer(Answer answer) { return new ReAuthAnswerImpl(answer); } @Override public ReAuthRequest createReAuthRequest(Request req) { return new ReAuthRequestImpl(req); } // Context Methods ---------------------------------------------------------- @Override @SuppressWarnings("unchecked") public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter Ro SessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override @SuppressWarnings("unchecked") public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter Ro SessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } // FIXME: add ctx methods proxy calls! @Override public void sessionSupervisionTimerExpired(ServerRoSession session) { // this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session); session.release(); } @Override @SuppressWarnings("unchecked") public void sessionSupervisionTimerReStarted(ServerRoSession session, ScheduledFuture future) { // TODO Complete this method. } @Override @SuppressWarnings("unchecked") public void sessionSupervisionTimerStarted(ServerRoSession session, ScheduledFuture future) { // TODO Complete this method. } @Override @SuppressWarnings("unchecked") public void sessionSupervisionTimerStopped(ServerRoSession session, ScheduledFuture future) { // TODO Complete this method. } @Override public void timeoutExpired(Request request) { // FIXME What should we do when there's a timeout? } @Override public void denyAccessOnDeliverFailure(ClientRoSession clientRoSessionImpl, Message request) { // TODO Complete this method. } @Override public void denyAccessOnFailureMessage(ClientRoSession clientRoSessionImpl) { // TODO Complete this method. } @Override public void denyAccessOnTxExpire(ClientRoSession clientRoSessionImpl) { // this.resourceAdaptor.sessionDestroyed(clientRoSessionImpl.getSessions().get(0).getSessionId(), // clientRoSessionImpl); clientRoSessionImpl.release(); } @Override public int getDefaultCCFHValue() { return defaultCreditControlFailureHandling; } @Override public int getDefaultDDFHValue() { return defaultDirectDebitingFailureHandling; } @Override public long getDefaultTxTimerValue() { return defaultTxTimerValue; } @Override public void grantAccessOnDeliverFailure(ClientRoSession clientRoSessionImpl, Message request) { // TODO Auto-generated method stub } @Override public void grantAccessOnFailureMessage(ClientRoSession clientRoSessionImpl) { // TODO Auto-generated method stub } @Override public void grantAccessOnTxExpire(ClientRoSession clientRoSessionImpl) { // TODO Auto-generated method stub } @Override public void indicateServiceError(ClientRoSession clientRoSessionImpl) { // TODO Auto-generated method stub } @Override public void txTimerExpired(ClientRoSession session) { // this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session); session.release(); } @Override public long[] getApplicationIds() { // FIXME: What should we do here? return new long[] { 4 }; } @Override public long getDefaultValidityTime() { return this.defaultValidityTime; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/AppRxSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.rx; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.rx.IRxSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public abstract class AppRxSessionImpl extends AppSessionImpl implements NetworkReqListener, StateMachine { protected Lock sendAndStateLock = new ReentrantLock(); //FIXME: those must be recreated from local resources! //FIXME: change this to single ref! protected transient List stateListeners = new CopyOnWriteArrayList(); public AppRxSessionImpl(ISessionFactory sf, IRxSessionData sessionData) { super(sf, sessionData); } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } @Override public void release() { super.release(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxAAAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.rx.events.RxAAAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxAAAnswerImpl extends AppAnswerEventImpl implements RxAAAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(RxAAAnswerImpl.class); public RxAAAnswerImpl(Request message, long resultCode) { super(message.createAnswer(resultCode)); } public RxAAAnswerImpl(Answer message) { super(message); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxAARequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rx; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rx.events.RxAARequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxAARequestImpl extends AppRequestEventImpl implements RxAARequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(RxAARequestImpl.class); public RxAARequestImpl(AppSession session, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); } public RxAARequestImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxAbortSessionAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.rx.events.RxAbortSessionAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxAbortSessionAnswerImpl extends AppAnswerEventImpl implements RxAbortSessionAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(RxAbortSessionAnswerImpl.class); public RxAbortSessionAnswerImpl(Request message, long resultCode) { super(message.createAnswer(resultCode)); } public RxAbortSessionAnswerImpl(Answer message) { super(message); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxAbortSessionRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rx; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rx.events.RxAbortSessionRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxAbortSessionRequestImpl extends AppRequestEventImpl implements RxAbortSessionRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(RxAbortSessionRequestImpl.class); public RxAbortSessionRequestImpl(AppSession session, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); } public RxAbortSessionRequestImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxLocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.rx; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rx.ClientRxSession; import org.jdiameter.api.rx.ServerRxSession; import org.jdiameter.client.impl.app.rx.ClientRxSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.rx.IRxSessionData; import org.jdiameter.server.impl.app.rx.ServerRxSessionDataLocalImpl; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxLocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IRxSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientRxSession.class)) { ClientRxSessionDataLocalImpl data = new ClientRxSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerRxSession.class)) { ServerRxSessionDataLocalImpl data = new ServerRxSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } throw new IllegalArgumentException(clazz.toString()); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxReAuthAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.rx.events.RxReAuthAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxReAuthAnswerImpl extends AppAnswerEventImpl implements RxReAuthAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(RxReAuthAnswerImpl.class); public RxReAuthAnswerImpl(Request message, long resultCode) { super(message.createAnswer(resultCode)); } public RxReAuthAnswerImpl(Answer message) { super(message); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxReAuthRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rx; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rx.events.RxReAuthRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxReAuthRequestImpl extends AppRequestEventImpl implements RxReAuthRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(RxReAuthRequestImpl.class); public RxReAuthRequestImpl(AppSession session, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); } public RxReAuthRequestImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rx; import java.util.concurrent.ScheduledFuture; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.Request; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.rx.ClientRxSession; import org.jdiameter.api.rx.ClientRxSessionListener; import org.jdiameter.api.rx.ServerRxSession; import org.jdiameter.api.rx.ServerRxSessionListener; import org.jdiameter.api.rx.events.RxAAAnswer; import org.jdiameter.api.rx.events.RxAARequest; import org.jdiameter.api.rx.events.RxAbortSessionAnswer; import org.jdiameter.api.rx.events.RxAbortSessionRequest; import org.jdiameter.api.rx.events.RxReAuthAnswer; import org.jdiameter.api.rx.events.RxReAuthRequest; import org.jdiameter.api.rx.events.RxSessionTermAnswer; import org.jdiameter.api.rx.events.RxSessionTermRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.rx.ClientRxSessionImpl; import org.jdiameter.client.impl.app.rx.IClientRxSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.rx.IClientRxSessionContext; import org.jdiameter.common.api.app.rx.IRxMessageFactory; import org.jdiameter.common.api.app.rx.IRxSessionData; import org.jdiameter.common.api.app.rx.IRxSessionFactory; import org.jdiameter.common.api.app.rx.IServerRxSessionContext; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.rx.IServerRxSessionData; import org.jdiameter.server.impl.app.rx.ServerRxSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default Diameter Rx Session Factory implementation. * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxSessionFactoryImpl implements IRxSessionFactory, ClientRxSessionListener, ServerRxSessionListener, StateChangeListener, IRxMessageFactory, IServerRxSessionContext, IClientRxSessionContext { // Message timeout value (in milliseconds) protected int defaultDirectDebitingFailureHandling = 0; protected int defaultAAFailureHandling = 0; // its seconds protected long defaultValidityTime = 60; protected long defaultTxTimerValue = 30; // local not replicated listeners: protected ClientRxSessionListener clientSessionListener; protected ServerRxSessionListener serverSessionListener; protected StateChangeListener stateListener; protected IServerRxSessionContext serverContextListener; protected IClientRxSessionContext clientContextListener; protected IRxMessageFactory messageFactory; protected static final Logger logger = LoggerFactory.getLogger(RxSessionFactoryImpl.class); protected ISessionDatasource iss; protected ISessionFactory sessionFactory = null; protected IAppSessionDataFactory sessionDataFactory; public RxSessionFactoryImpl(SessionFactory sessionFactory) { super(); this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IRxSessionData.class); if (this.sessionDataFactory == null) { logger.debug("Initialized Rx SessionDataFactory is null"); } } public RxSessionFactoryImpl(SessionFactory sessionFactory, int defaultDirectDebitingFailureHandling, int defaultAAFailureHandling, long defaultValidityTime, long defaultTxTimerValue) { this(sessionFactory); this.defaultDirectDebitingFailureHandling = defaultDirectDebitingFailureHandling; this.defaultAAFailureHandling = defaultAAFailureHandling; this.defaultValidityTime = defaultValidityTime; this.defaultTxTimerValue = defaultTxTimerValue; } /** * @return the clientSessionListener */ @Override public ClientRxSessionListener getClientSessionListener() { return clientSessionListener != null ? clientSessionListener : this; } /** * @param clientSessionListener the clientSessionListener to set */ @Override public void setClientSessionListener(final ClientRxSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the serverSessionListener */ @Override public ServerRxSessionListener getServerSessionListener() { return serverSessionListener != null ? serverSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerRxSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the serverContextListener */ @Override public IServerRxSessionContext getServerContextListener() { return serverContextListener != null ? serverContextListener : this; } /** * @param serverContextListener the serverContextListener to set */ @Override public void setServerContextListener(IServerRxSessionContext serverContextListener) { this.serverContextListener = serverContextListener; } /** * @return the clientContextListener */ @Override public IClientRxSessionContext getClientContextListener() { return clientContextListener != null ? clientContextListener : this; } /** * @return the messageFactory */ @Override public IRxMessageFactory getMessageFactory() { return messageFactory != null ? messageFactory : this; } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(final IRxMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @param clientContextListener the clientContextListener to set */ @Override public void setClientContextListener(IClientRxSessionContext clientContextListener) { this.clientContextListener = clientContextListener; } /** * @return the sessionFactory */ public SessionFactory getSessionFactory() { return sessionFactory; } /** * @param sessionFactory the sessionFactory to set */ public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = (ISessionFactory) sessionFactory; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { return stateListener != null ? stateListener : this; } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ClientRxSession.class) { IClientRxSessionData sessionData = (IClientRxSessionData) this.sessionDataFactory .getAppSessionData(ClientRxSession.class, sessionId); ClientRxSessionImpl clientSession = new ClientRxSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerRxSession.class) { IServerRxSessionData sessionData = (IServerRxSessionData) this.sessionDataFactory .getAppSessionData(ServerRxSession.class, sessionId); ServerRxSessionImpl serverSession = new ServerRxSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getServerSessionListener(), this.getServerContextListener(), this.getStateListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientRxSession.class + "," + ServerRxSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Rx Session.", e); } return appSession; } @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; try { // FIXME: if (aClass == ClientRxSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientRxSessionData sessionData = (IClientRxSessionData) this.sessionDataFactory .getAppSessionData(ClientRxSession.class, sessionId); sessionData.setApplicationId(applicationId); ClientRxSessionImpl clientSession = new ClientRxSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientSessionListener(), this.getClientContextListener(), this.getStateListener()); // this goes first! iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else if (aClass == ServerRxSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerRxSessionData sessionData = (IServerRxSessionData) this.sessionDataFactory .getAppSessionData(ServerRxSession.class, sessionId); sessionData.setApplicationId(applicationId); ServerRxSessionImpl serverSession = new ServerRxSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getServerSessionListener(), this.getServerContextListener(), this.getStateListener()); iss.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ClientRxSession.class + "," + ServerRxSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Rx Session.", e); } return appSession; } // Default implementation of methods so there are no exception! // Message Handlers -------------------------------------------------------- @Override public void doAARequest(ServerRxSession session, RxAARequest request) throws InternalException { } @Override public void doAAAnswer(ClientRxSession session, RxAARequest request, RxAAAnswer answer) throws InternalException { } @Override public void doReAuthRequest(ClientRxSession session, RxReAuthRequest request) throws InternalException { } @Override public void doReAuthAnswer(ServerRxSession session, RxReAuthRequest request, RxReAuthAnswer answer) throws InternalException { } @Override public void doAbortSessionRequest(ClientRxSession session, RxAbortSessionRequest request) throws InternalException { } @Override public void doAbortSessionAnswer(ServerRxSession session, RxAbortSessionRequest request, RxAbortSessionAnswer answer) throws InternalException { } @Override public void doSessionTermRequest(ServerRxSession session, RxSessionTermRequest request) throws InternalException { } @Override public void doSessionTermAnswer(ClientRxSession session, RxSessionTermRequest request, RxSessionTermAnswer answer) throws InternalException { } @Override public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { } // Message Factory Methods ------------------------------------------------- @Override public RxAAAnswer createAAAnswer(Answer answer) { return new RxAAAnswerImpl(answer); } @Override public RxAARequest createAARequest(Request req) { return new RxAARequestImpl(req); } @Override public RxReAuthAnswer createReAuthAnswer(Answer answer) { return new RxReAuthAnswerImpl(answer); } @Override public RxReAuthRequest createReAuthRequest(Request req) { return new RxReAuthRequestImpl(req); } @Override public RxSessionTermAnswer createSessionTermAnswer(Answer answer) { return new RxSessionTermAnswerImpl(answer); } @Override public RxSessionTermRequest createSessionTermRequest(Request req) { return new RxSessionTermRequestImpl(req); } @Override public RxAbortSessionAnswer createAbortSessionAnswer(Answer answer) { return new RxAbortSessionAnswerImpl(answer); } @Override public RxAbortSessionRequest createAbortSessionRequest(Request req) { return new RxAbortSessionRequestImpl(req); } // Context Methods ---------------------------------------------------------- @Override public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter Rx SessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter Rx SessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } // FIXME: add ctx methods proxy calls! @Override public void sessionSupervisionTimerExpired(ServerRxSession session) { // this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session); session.release(); } @Override public void sessionSupervisionTimerReStarted(ServerRxSession session, ScheduledFuture future) { // TODO Complete this method. } @Override public void sessionSupervisionTimerStarted(ServerRxSession session, ScheduledFuture future) { // TODO Complete this method. } @Override public void sessionSupervisionTimerStopped(ServerRxSession session, ScheduledFuture future) { // TODO Complete this method. } public void timeoutExpired(Request request) { // FIXME What should we do when there's a timeout? } @Override public void denyAccessOnDeliverFailure(ClientRxSession clientRxSessionImpl, Message request) { // TODO Complete this method. } @Override public void denyAccessOnFailureMessage(ClientRxSession clientRxSessionImpl) { // TODO Complete this method. } public void denyAccessOnTxExpire(ClientRxSession clientRxSessionImpl) { // this.resourceAdaptor.sessionDestroyed(clientRxSessionImpl.getSessions().get(0).getSessionId(), // clientRxSessionImpl); clientRxSessionImpl.release(); } @Override public void grantAccessOnDeliverFailure(ClientRxSession clientRxSessionImpl, Message request) { // TODO Auto-generated method stub } @Override public void grantAccessOnFailureMessage(ClientRxSession clientRxSessionImpl) { // TODO Auto-generated method stub } public void grantAccessOnTxExpire(ClientRxSession clientRxSessionImpl) { // TODO Auto-generated method stub } @Override public void indicateServiceError(ClientRxSession clientRxSessionImpl) { // TODO Auto-generated method stub } @Override public long[] getApplicationIds() { // FIXME: What should we do here? return new long[] { 16777236 }; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxSessionTermAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rx; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.rx.events.RxSessionTermAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxSessionTermAnswerImpl extends AppAnswerEventImpl implements RxSessionTermAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(RxSessionTermAnswerImpl.class); public RxSessionTermAnswerImpl(Request message, long resultCode) { super(message.createAnswer(resultCode)); } public RxSessionTermAnswerImpl(Answer message) { super(message); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/rx/RxSessionTermRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.rx; import org.jdiameter.api.Request; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rx.events.RxSessionTermRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RxSessionTermRequestImpl extends AppRequestEventImpl implements RxSessionTermRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(RxSessionTermRequestImpl.class); public RxSessionTermRequestImpl(AppSession session, String destRealm, String destHost) { super(session.getSessions().get(0).createRequest(code, session.getSessionAppId(), destRealm, destHost)); } public RxSessionTermRequestImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s13/JMEIdentityCheckAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.s13; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.s13.events.JMEIdentityCheckAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings("all") //3rd party lib public class JMEIdentityCheckAnswerImpl extends AppAnswerEventImpl implements JMEIdentityCheckAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(JMEIdentityCheckAnswerImpl.class); public JMEIdentityCheckAnswerImpl(Answer answer) { super(answer); } public JMEIdentityCheckAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } @Override public boolean isEquipmentStatusAVPPresent() { return super.message.getAvps().getAvp(Avp.EQUIPMENT_STATUS) != null; } @Override public int getEquipmentStatus() { Avp equipmentStatusAvp = super.message.getAvps().getAvp(Avp.EQUIPMENT_STATUS); if (equipmentStatusAvp != null) { try { return equipmentStatusAvp.getInteger32(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain Equipment-Status AVP value", e); } } return -1; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s13/JMEIdentityCheckRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.s13; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Message; import org.jdiameter.api.s13.events.JMEIdentityCheckRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings("all") //3rd party lib public class JMEIdentityCheckRequestImpl extends AppRequestEventImpl implements JMEIdentityCheckRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(JMEIdentityCheckRequestImpl.class); public JMEIdentityCheckRequestImpl(Message message) { super(message); message.setRequest(true); } @Override public Avp getTerminalInformationAvp() { return super.message.getAvps().getAvp(Avp.TERMINAL_INFORMATION); } @Override public boolean hasIMEI() { Avp terminalInfoAvp = super.message.getAvps().getAvp(Avp.TERMINAL_INFORMATION); if (terminalInfoAvp != null) { try { return terminalInfoAvp.getGrouped().getAvp(Avp.TGPP_IMEI) != null; } catch (AvpDataException ex) { logger.debug("Failure trying to obtain (Terminal-Information) IMEI AVP value", ex); } } return false; } @Override public String getIMEI() { Avp terminalInfoAvp = super.message.getAvps().getAvp(Avp.TERMINAL_INFORMATION); if (terminalInfoAvp != null) { try { Avp imei = terminalInfoAvp.getGrouped().getAvp(Avp.TGPP_IMEI); if (imei != null) { return imei.getUTF8String(); } } catch (AvpDataException ex) { logger.debug("Failure trying to obtain (Terminal-Information) IMEI AVP value", ex); } } return null; } @Override public boolean hasTgpp2MEID() { Avp terminalInfoAvp = super.message.getAvps().getAvp(Avp.TERMINAL_INFORMATION); if (terminalInfoAvp != null) { try { return terminalInfoAvp.getGrouped().getAvp(Avp.TGPP2_MEID) != null; } catch (AvpDataException ex) { logger.debug("Failure trying to obtain (Terminal-Information) MEID AVP value", ex); } } return false; } @Override public byte[] getTgpp2MEID() { Avp terminalInfoAvp = super.message.getAvps().getAvp(Avp.TERMINAL_INFORMATION); if (terminalInfoAvp != null) { try { Avp meid = terminalInfoAvp.getGrouped().getAvp(Avp.TGPP2_MEID); if (meid != null) { return meid.getOctetString(); } } catch (AvpDataException ex) { logger.debug("Failure trying to obtain (Terminal-Information) MEID AVP value", ex); } } return null; } @Override public boolean hasSoftwareVersion() { Avp terminalInfoAvp = super.message.getAvps().getAvp(Avp.TERMINAL_INFORMATION); if (terminalInfoAvp != null) { try { return terminalInfoAvp.getGrouped().getAvp(Avp.SOFTWARE_VERSION) != null; } catch (AvpDataException ex) { logger.debug("Failure trying to obtain (Terminal-Information) Software-Version AVP value", ex); } } return false; } @Override public String getSoftwareVersion() { Avp terminalInfoAvp = super.message.getAvps().getAvp(Avp.TERMINAL_INFORMATION); if (terminalInfoAvp != null) { try { Avp softwareVersion = terminalInfoAvp.getGrouped().getAvp(Avp.SOFTWARE_VERSION); if (softwareVersion != null) { return softwareVersion.getUTF8String(); } } catch (AvpDataException ex) { logger.debug("Failure trying to obtain (Terminal-Information) Software-Version AVP value", ex); } } return null; } @Override public boolean isUserNameAVPPresent() { return super.message.getAvps().getAvp(Avp.USER_NAME) != null; } @Override public String getUserName() { Avp userNameAvp = super.message.getAvps().getAvp(Avp.USER_NAME); if (userNameAvp != null) { try { return userNameAvp.getUTF8String(); } catch (AvpDataException e) { logger.debug("Failure trying to obtain User-Name AVP value", e); } } return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s13/S13LocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.s13; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.s13.ClientS13Session; import org.jdiameter.api.s13.ServerS13Session; import org.jdiameter.client.impl.app.s13.ClientS13SessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.server.impl.app.s13.ServerS13SessionDataLocalImpl; @SuppressWarnings("all") //3rd party lib public class S13LocalSessionDataFactory implements IAppSessionDataFactory { @Override public IS13SessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientS13Session.class)) { ClientS13SessionDataLocalImpl data = new ClientS13SessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerS13Session.class)) { ServerS13SessionDataLocalImpl data = new ServerS13SessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else { throw new IllegalArgumentException("Invalid Session Class: " + clazz.toString()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s13/S13LocalSessionDataImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.s13; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.common.api.app.s13.S13SessionState; @SuppressWarnings("all") //3rd party lib public class S13LocalSessionDataImpl extends AppSessionDataLocalImpl implements IS13SessionData { protected S13SessionState state = S13SessionState.IDLE; protected Request buffer; protected Serializable tsTimerId; @Override public void setS13SessionState(S13SessionState state) { this.state = state; } @Override public S13SessionState getS13SessionState() { return this.state; } @Override public Serializable getTsTimerId() { return this.tsTimerId; } @Override public void setTsTimerId(Serializable tid) { this.tsTimerId = tid; } @Override public void setBuffer(Request buffer) { this.buffer = buffer; } @Override public Request getBuffer() { return this.buffer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s13/S13Session.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.s13; import java.io.Serializable; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.s13.IS13MessageFactory; import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.common.impl.app.AppSessionImpl; @SuppressWarnings("all") //3rd party lib public abstract class S13Session extends AppSessionImpl implements NetworkReqListener, StateMachine { public static final int _TX_TIMEOUT = 30 * 1000; protected Lock sendAndStateLock = new ReentrantLock(); protected transient List stateListeners = new CopyOnWriteArrayList(); protected transient IS13MessageFactory messageFactory; protected static final String TIMER_NAME_MSG_TIMEOUT = "MSG_TIMEOUT"; protected IS13SessionData sessionData; public S13Session(ISessionFactory sf, IS13SessionData sessionData) { super(sf, sessionData); this.sessionData = sessionData; } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } @Override public boolean isStateless() { return true; } @Override public boolean isReplicable() { return false; } protected void startMsgTimer() { try { sendAndStateLock.lock(); sessionData.setTsTimerId(super.timerFacility.schedule(getSessionId(), TIMER_NAME_MSG_TIMEOUT, _TX_TIMEOUT)); } finally { sendAndStateLock.unlock(); } } protected void cancelMsgTimer() { try { sendAndStateLock.lock(); final Serializable timerId = this.sessionData.getTsTimerId(); if (timerId == null) { return; } super.timerFacility.cancel(timerId); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } S13Session other = (S13Session) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s13/S13SessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.s13; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.s13.ClientS13Session; import org.jdiameter.api.s13.ClientS13SessionListener; import org.jdiameter.api.s13.ServerS13Session; import org.jdiameter.api.s13.ServerS13SessionListener; import org.jdiameter.api.s13.events.JMEIdentityCheckAnswer; import org.jdiameter.api.s13.events.JMEIdentityCheckRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.s13.IClientS13SessionData; import org.jdiameter.client.impl.app.s13.S13ClientSessionImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.s13.IS13MessageFactory; import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.common.api.app.s13.IS13SessionFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.s13.IServerS13SessionData; import org.jdiameter.server.impl.app.s13.S13ServerSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings("all") //3rd party lib public class S13SessionFactoryImpl implements IS13SessionFactory, ServerS13SessionListener, ClientS13SessionListener, IS13MessageFactory, StateChangeListener { private static final Logger logger = LoggerFactory.getLogger(S13SessionFactoryImpl.class); protected ISessionFactory sessionFactory; protected ServerS13SessionListener serverSessionListener; protected ClientS13SessionListener clientSessionListener; protected IS13MessageFactory messageFactory; protected StateChangeListener stateListener; protected ISessionDatasource iss; protected IAppSessionDataFactory sessionDataFactory; public S13SessionFactoryImpl() { } ; public S13SessionFactoryImpl(SessionFactory sessionFactory) { super(); init(sessionFactory); } public void init(SessionFactory sessionFactory) { this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IS13SessionData.class); } /** * @return the serverSessionListener */ @Override public ServerS13SessionListener getServerSessionListener() { return serverSessionListener != null ? serverSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerS13SessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the serverSessionListener */ @Override public ClientS13SessionListener getClientSessionListener() { return clientSessionListener != null ? clientSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setClientSessionListener(ClientS13SessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the messageFactory */ @Override public IS13MessageFactory getMessageFactory() { return messageFactory != null ? messageFactory : this; } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(IS13MessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { return stateListener != null ? stateListener : this; } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ServerS13Session.class) { IServerS13SessionData sessionData = (IServerS13SessionData) this.sessionDataFactory .getAppSessionData(ServerS13Session.class, sessionId); S13ServerSessionImpl serverSession = new S13ServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else if (aClass == ClientS13Session.class) { IClientS13SessionData sessionData = (IClientS13SessionData) this.sessionDataFactory .getAppSessionData(ClientS13Session.class, sessionId); S13ClientSessionImpl clientSession = new S13ClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else { throw new IllegalArgumentException( "Wrong session class: " + aClass + ". Supported[" + ServerS13Session.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new S13 Session.", e); } return appSession; } @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; try { if (aClass == ServerS13Session.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerS13SessionData sessionData = (IServerS13SessionData) this.sessionDataFactory .getAppSessionData(ServerS13Session.class, sessionId); sessionData.setApplicationId(applicationId); S13ServerSessionImpl serverSession = new S13ServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); iss.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else if (aClass == ClientS13Session.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientS13SessionData sessionData = (IClientS13SessionData) this.sessionDataFactory .getAppSessionData(ClientS13Session.class, sessionId); sessionData.setApplicationId(applicationId); S13ClientSessionImpl clientSession = new S13ClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else { throw new IllegalArgumentException( "Wrong session class: " + aClass + ". Supported[" + ServerS13Session.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new S13 Session.", e); } return appSession; } @Override public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter S13 Session Factory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } @Override public long getApplicationId() { return 16777252; } @Override public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter S13 Session Factory :: stateChanged :: Session, [{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } @Override public JMEIdentityCheckAnswer createMEIdentityCheckAnswer(Answer answer) { return new JMEIdentityCheckAnswerImpl(answer); } @Override public JMEIdentityCheckRequest createMEIdentityCheckRequest(Request request) { return new JMEIdentityCheckRequestImpl(request); } @Override public void doMEIdentityCheckRequestEvent(ServerS13Session appSession, JMEIdentityCheckRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S13 Session Factory :: doMEIdentityCheckRequestEvent :: appSession[{}], Request[{}]", appSession, request); } @Override public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S13 Session Factory :: doOtherEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doMEIdentityCheckAnswerEvent(ClientS13Session appSession, JMEIdentityCheckRequest request, JMEIdentityCheckAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S13 Session Factory :: doMEIdentityCheckAnswerEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JAuthenticationInformationAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s6a.events.JAuthenticationInformationAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class JAuthenticationInformationAnswerImpl extends AppAnswerEventImpl implements JAuthenticationInformationAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JAuthenticationInformationAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public JAuthenticationInformationAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JAuthenticationInformationRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Message; import org.jdiameter.api.s6a.events.JAuthenticationInformationRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class JAuthenticationInformationRequestImpl extends AppRequestEventImpl implements JAuthenticationInformationRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JAuthenticationInformationRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JCancelLocationAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s6a.events.JCancelLocationAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JCancelLocationAnswerImpl extends AppAnswerEventImpl implements JCancelLocationAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JCancelLocationAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public JCancelLocationAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JCancelLocationRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Message; import org.jdiameter.api.s6a.events.JCancelLocationRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JCancelLocationRequestImpl extends AppRequestEventImpl implements JCancelLocationRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JCancelLocationRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JDeleteSubscriberDataAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s6a.events.JDeleteSubscriberDataAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JDeleteSubscriberDataAnswerImpl extends AppAnswerEventImpl implements JDeleteSubscriberDataAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JDeleteSubscriberDataAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public JDeleteSubscriberDataAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JDeleteSubscriberDataRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Message; import org.jdiameter.api.s6a.events.JDeleteSubscriberDataRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JDeleteSubscriberDataRequestImpl extends AppRequestEventImpl implements JDeleteSubscriberDataRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JDeleteSubscriberDataRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JInsertSubscriberDataAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s6a.events.JInsertSubscriberDataAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JInsertSubscriberDataAnswerImpl extends AppAnswerEventImpl implements JInsertSubscriberDataAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JInsertSubscriberDataAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public JInsertSubscriberDataAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JInsertSubscriberDataRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Message; import org.jdiameter.api.s6a.events.JInsertSubscriberDataRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JInsertSubscriberDataRequestImpl extends AppRequestEventImpl implements JInsertSubscriberDataRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JInsertSubscriberDataRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JNotifyAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s6a.events.JNotifyAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JNotifyAnswerImpl extends AppAnswerEventImpl implements JNotifyAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JNotifyAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public JNotifyAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JNotifyRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Message; import org.jdiameter.api.s6a.events.JNotifyRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JNotifyRequestImpl extends AppRequestEventImpl implements JNotifyRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JNotifyRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JPurgeUEAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s6a.events.JPurgeUEAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class JPurgeUEAnswerImpl extends AppAnswerEventImpl implements JPurgeUEAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JPurgeUEAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public JPurgeUEAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JPurgeUERequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Message; import org.jdiameter.api.s6a.events.JPurgeUERequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class JPurgeUERequestImpl extends AppRequestEventImpl implements JPurgeUERequest { private static final long serialVersionUID = 1L; /** * @param message */ public JPurgeUERequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JResetAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s6a.events.JResetAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JResetAnswerImpl extends AppAnswerEventImpl implements JResetAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JResetAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public JResetAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JResetRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Message; import org.jdiameter.api.s6a.events.JResetRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class JResetRequestImpl extends AppRequestEventImpl implements JResetRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JResetRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JUpdateLocationAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.s6a.events.JUpdateLocationAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class JUpdateLocationAnswerImpl extends AppAnswerEventImpl implements JUpdateLocationAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public JUpdateLocationAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public JUpdateLocationAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/JUpdateLocationRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Message; import org.jdiameter.api.s6a.events.JUpdateLocationRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class JUpdateLocationRequestImpl extends AppRequestEventImpl implements JUpdateLocationRequest { private static final long serialVersionUID = 1L; /** * @param message */ public JUpdateLocationRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/S6aLocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.s6a.ClientS6aSession; import org.jdiameter.api.s6a.ServerS6aSession; import org.jdiameter.client.impl.app.s6a.ClientS6aSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.s6a.IS6aSessionData; import org.jdiameter.server.impl.app.s6a.ServerS6aSessionDataLocalImpl; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class S6aLocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IS6aSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientS6aSession.class)) { ClientS6aSessionDataLocalImpl data = new ClientS6aSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerS6aSession.class)) { ServerS6aSessionDataLocalImpl data = new ServerS6aSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else { throw new IllegalArgumentException("Invalid Session Class: " + clazz.toString()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/S6aLocalSessionDataImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.s6a.IS6aSessionData; import org.jdiameter.common.api.app.s6a.S6aSessionState; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class S6aLocalSessionDataImpl extends AppSessionDataLocalImpl implements IS6aSessionData { protected S6aSessionState state = S6aSessionState.IDLE; protected Request buffer; protected Serializable tsTimerId; @Override public void setS6aSessionState(S6aSessionState state) { this.state = state; } @Override public S6aSessionState getS6aSessionState() { return this.state; } @Override public Serializable getTsTimerId() { return this.tsTimerId; } @Override public void setTsTimerId(Serializable tid) { this.tsTimerId = tid; } @Override public void setBuffer(Request buffer) { this.buffer = buffer; } @Override public Request getBuffer() { return this.buffer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/S6aSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import java.io.Serializable; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.s6a.IS6aMessageFactory; import org.jdiameter.common.api.app.s6a.IS6aSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public abstract class S6aSession extends AppSessionImpl implements NetworkReqListener, StateMachine { public static final int _TX_TIMEOUT = 30 * 1000; protected Lock sendAndStateLock = new ReentrantLock(); protected transient List stateListeners = new CopyOnWriteArrayList(); protected transient IS6aMessageFactory messageFactory; protected static final String TIMER_NAME_MSG_TIMEOUT = "MSG_TIMEOUT"; protected IS6aSessionData sessionData; public S6aSession(ISessionFactory sf, IS6aSessionData sessionData) { super(sf, sessionData); this.sessionData = sessionData; } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } @Override public boolean isStateless() { return true; } @Override public boolean isReplicable() { return false; } protected void startMsgTimer() { try { sendAndStateLock.lock(); sessionData.setTsTimerId(super.timerFacility.schedule(getSessionId(), TIMER_NAME_MSG_TIMEOUT, _TX_TIMEOUT)); } finally { sendAndStateLock.unlock(); } } protected void cancelMsgTimer() { try { sendAndStateLock.lock(); final Serializable timerId = this.sessionData.getTsTimerId(); if (timerId == null) { return; } super.timerFacility.cancel(timerId); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } S6aSession other = (S6aSession) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/s6a/S6aSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.s6a.ClientS6aSession; import org.jdiameter.api.s6a.ClientS6aSessionListener; import org.jdiameter.api.s6a.ServerS6aSession; import org.jdiameter.api.s6a.ServerS6aSessionListener; import org.jdiameter.api.s6a.events.*; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.s6a.IClientS6aSessionData; import org.jdiameter.client.impl.app.s6a.S6aClientSessionImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.s6a.IS6aMessageFactory; import org.jdiameter.common.api.app.s6a.IS6aSessionData; import org.jdiameter.common.api.app.s6a.IS6aSessionFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.s6a.IServerS6aSessionData; import org.jdiameter.server.impl.app.s6a.S6aServerSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class S6aSessionFactoryImpl implements IS6aSessionFactory, ServerS6aSessionListener, ClientS6aSessionListener, IS6aMessageFactory, StateChangeListener { private static final Logger logger = LoggerFactory.getLogger(S6aSessionFactoryImpl.class); protected ISessionFactory sessionFactory; protected ServerS6aSessionListener serverSessionListener; protected ClientS6aSessionListener clientSessionListener; protected IS6aMessageFactory messageFactory; protected StateChangeListener stateListener; protected ISessionDatasource iss; protected IAppSessionDataFactory sessionDataFactory; public S6aSessionFactoryImpl(SessionFactory sessionFactory) { super(); this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(IS6aSessionData.class); } /** * @return the serverSessionListener */ @Override public ServerS6aSessionListener getServerSessionListener() { return serverSessionListener != null ? serverSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setServerSessionListener(ServerS6aSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the serverSessionListener */ @Override public ClientS6aSessionListener getClientSessionListener() { return clientSessionListener != null ? clientSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ @Override public void setClientSessionListener(ClientS6aSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the messageFactory */ @Override public IS6aMessageFactory getMessageFactory() { return messageFactory != null ? messageFactory : this; } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(IS6aMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @return the stateListener */ @Override public StateChangeListener getStateListener() { return stateListener != null ? stateListener : this; } /** * @param stateListener the stateListener to set */ @Override public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ServerS6aSession.class) { IServerS6aSessionData sessionData = (IServerS6aSessionData) this.sessionDataFactory .getAppSessionData(ServerS6aSession.class, sessionId); S6aServerSessionImpl serverSession = new S6aServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else if (aClass == ClientS6aSession.class) { IClientS6aSessionData sessionData = (IClientS6aSessionData) this.sessionDataFactory .getAppSessionData(ClientS6aSession.class, sessionId); S6aClientSessionImpl clientSession = new S6aClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else { throw new IllegalArgumentException( "Wrong session class: " + aClass + ". Supported[" + ServerS6aSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new S6a Session.", e); } return appSession; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionFactory#getNewSession(java.lang.String, java.lang.Class, * org.jdiameter.api.ApplicationId, java.lang.Object[]) */ @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; if (aClass == ServerS6aSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerS6aSessionData sessionData = (IServerS6aSessionData) this.sessionDataFactory .getAppSessionData(ServerS6aSession.class, sessionId); sessionData.setApplicationId(applicationId); S6aServerSessionImpl serverSession = new S6aServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); iss.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else if (aClass == ClientS6aSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientS6aSessionData sessionData = (IClientS6aSessionData) this.sessionDataFactory .getAppSessionData(ClientS6aSession.class, sessionId); sessionData.setApplicationId(applicationId); S6aClientSessionImpl clientSession = new S6aClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else { throw new IllegalArgumentException( "Wrong session class: " + aClass + ". Supported[" + ServerS6aSession.class + "]"); } return appSession; } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Enum, java.lang.Enum) */ @Override public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter S6a Session Factory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } @Override public long getApplicationId() { return 16777251; } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter S6a Session Factory :: stateChanged :: Session, [{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } @Override public JAuthenticationInformationAnswer createAuthenticationInformationAnswer(Answer answer) { return new JAuthenticationInformationAnswerImpl(answer); } @Override public JAuthenticationInformationRequest createAuthenticationInformationRequest(Request request) { return new JAuthenticationInformationRequestImpl(request); } @Override public JUpdateLocationRequest createUpdateLocationRequest(Request request) { return new JUpdateLocationRequestImpl(request); } @Override public JUpdateLocationAnswer createUpdateLocationAnswer(Answer answer) { return new JUpdateLocationAnswerImpl(answer); } @Override public JPurgeUERequest createPurgeUERequest(Request request) { return new JPurgeUERequestImpl(request); } @Override public JPurgeUEAnswer createPurgeUEAnswer(Answer answer) { return new JPurgeUEAnswerImpl(answer); } @Override public JCancelLocationRequest createCancelLocationRequest(Request request) { return new JCancelLocationRequestImpl(request); } @Override public JCancelLocationAnswer createCancelLocationAnswer(Answer answer) { return new JCancelLocationAnswerImpl(answer); } @Override public JInsertSubscriberDataRequest createInsertSubscriberDataRequest(Request request) { return new JInsertSubscriberDataRequestImpl(request); } @Override public JInsertSubscriberDataAnswer createInsertSubscriberDataAnswer(Answer answer) { return new JInsertSubscriberDataAnswerImpl(answer); } @Override public JDeleteSubscriberDataRequest createDeleteSubscriberDataRequest(Request request) { return new JDeleteSubscriberDataRequestImpl(request); } @Override public JDeleteSubscriberDataAnswer createDeleteSubscriberDataAnswer(Answer answer) { return new JDeleteSubscriberDataAnswerImpl(answer); } @Override public JResetRequest createResetRequest(Request request) { return new JResetRequestImpl(request); } @Override public JResetAnswer createResetAnswer(Answer answer) { return new JResetAnswerImpl(answer); } @Override public JNotifyRequest createNotifyRequest(Request request) { return new JNotifyRequestImpl(request); } @Override public JNotifyAnswer createNotifyAnswer(Answer answer) { return new JNotifyAnswerImpl(answer); } @Override public void doAuthenticationInformationRequestEvent(ServerS6aSession appSession, JAuthenticationInformationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doAuthenticationInformationRequest :: appSession[{}], Request[{}]", appSession, request); } @Override public void doPurgeUERequestEvent(ServerS6aSession appSession, JPurgeUERequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doPurgeUERequest :: appSession[{}], Request[{}]", appSession, request); } @Override public void doUpdateLocationRequestEvent(ServerS6aSession appSession, JUpdateLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doUpdateLocationRequest :: appSession[{}], Request[{}]", appSession, request); } @Override public void doNotifyRequestEvent(ServerS6aSession appSession, JNotifyRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doNotifyRequest :: appSession[{}], Request[{}]", appSession, request); } @Override public void doCancelLocationAnswerEvent(ServerS6aSession appSession, JCancelLocationRequest request, JCancelLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doCancelLocationAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doInsertSubscriberDataAnswerEvent(ServerS6aSession appSession, JInsertSubscriberDataRequest request, JInsertSubscriberDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doInsertSubscriberDataAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doDeleteSubscriberDataAnswerEvent(ServerS6aSession appSession, JDeleteSubscriberDataRequest request, JDeleteSubscriberDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doDeleteSubscriberDataAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doResetAnswerEvent(ServerS6aSession appSession, JResetRequest request, JResetAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doResetAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doOtherEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doCancelLocationRequestEvent(ClientS6aSession appSession, JCancelLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doCancelLocationRequest :: appSession[{}], Request[{}]", new Object[] { appSession, request }); } @Override public void doInsertSubscriberDataRequestEvent(ClientS6aSession appSession, JInsertSubscriberDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doInsertSubscriberDataRequest :: appSession[{}], Request[{}]", new Object[] { appSession, request }); } @Override public void doDeleteSubscriberDataRequestEvent(ClientS6aSession appSession, JDeleteSubscriberDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doDeleteSubscriberDataRequest :: appSession[{}], Request[{}]", new Object[] { appSession, request }); } @Override public void doResetRequestEvent(ClientS6aSession appSession, JResetRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doResetRequest :: appSession[{}], Request[{}]", new Object[] { appSession, request }); } @Override public void doAuthenticationInformationAnswerEvent(ClientS6aSession appSession, JAuthenticationInformationRequest request, JAuthenticationInformationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info( "Diameter S6a Session Factory :: doAuthenticationInformationAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doPurgeUEAnswerEvent(ClientS6aSession appSession, JPurgeUERequest request, JPurgeUEAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doPurgeUEAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doUpdateLocationAnswerEvent(ClientS6aSession appSession, JUpdateLocationRequest request, JUpdateLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doUpdateLocationAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } @Override public void doNotifyAnswerEvent(ClientS6aSession appSession, JNotifyRequest request, JNotifyAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter S6a Session Factory :: doNotifyAnswer :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/ProfileUpdateAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.sh.events.ProfileUpdateAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ProfileUpdateAnswerImpl extends AppAnswerEventImpl implements ProfileUpdateAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public ProfileUpdateAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public ProfileUpdateAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public ProfileUpdateAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public ProfileUpdateAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/ProfileUpdateRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import org.jdiameter.api.Request; import org.jdiameter.api.sh.events.ProfileUpdateRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ProfileUpdateRequestImpl extends AppRequestEventImpl implements ProfileUpdateRequest { private static final long serialVersionUID = 1L; public ProfileUpdateRequestImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/PushNotificationAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.sh.events.PushNotificationAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class PushNotificationAnswerImpl extends AppAnswerEventImpl implements PushNotificationAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public PushNotificationAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public PushNotificationAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public PushNotificationAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public PushNotificationAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/PushNotificationRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import org.jdiameter.api.Request; import org.jdiameter.api.sh.events.PushNotificationRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class PushNotificationRequestImpl extends AppRequestEventImpl implements PushNotificationRequest { private static final long serialVersionUID = 1L; public PushNotificationRequestImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/ShLocalSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.sh.ClientShSession; import org.jdiameter.api.sh.ServerShSession; import org.jdiameter.client.impl.app.sh.ShClientSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.sh.IShSessionData; import org.jdiameter.server.impl.app.sh.ShServerSessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ShLocalSessionDataFactory implements IAppSessionDataFactory { /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IShSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientShSession.class)) { ShClientSessionDataLocalImpl data = new ShClientSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerShSession.class)) { ShServerSessionDataLocalImpl data = new ShServerSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } throw new IllegalArgumentException(clazz.toString()); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/ShSession.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.sh.IShSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public abstract class ShSession extends AppSessionImpl implements NetworkReqListener, StateMachine { protected Lock sendAndStateLock = new ReentrantLock(); protected transient List stateListeners = new CopyOnWriteArrayList(); public ShSession(ISessionFactory sf, IShSessionData data) { super(sf, data); } @Override public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @Override public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } @Override public void release() { //stateListeners.clear(); super.release(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/ShSessionFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.common.impl.app.sh; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.sh.ClientShSession; import org.jdiameter.api.sh.ClientShSessionListener; import org.jdiameter.api.sh.ServerShSession; import org.jdiameter.api.sh.ServerShSessionListener; import org.jdiameter.api.sh.events.ProfileUpdateAnswer; import org.jdiameter.api.sh.events.ProfileUpdateRequest; import org.jdiameter.api.sh.events.PushNotificationAnswer; import org.jdiameter.api.sh.events.PushNotificationRequest; import org.jdiameter.api.sh.events.SubscribeNotificationsAnswer; import org.jdiameter.api.sh.events.SubscribeNotificationsRequest; import org.jdiameter.api.sh.events.UserDataAnswer; import org.jdiameter.api.sh.events.UserDataRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.sh.IShClientSessionData; import org.jdiameter.client.impl.app.sh.ShClientSessionImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.sh.IShMessageFactory; import org.jdiameter.common.api.app.sh.IShSessionData; import org.jdiameter.common.api.app.sh.IShSessionFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.sh.IShServerSessionData; import org.jdiameter.server.impl.app.sh.ShServerSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ShSessionFactoryImpl implements IShSessionFactory, StateChangeListener, ClientShSessionListener, ServerShSessionListener, IShMessageFactory { protected static final Logger logger = LoggerFactory.getLogger(ShSessionFactoryImpl.class); // Listeners provided by developer ---------------------------------------- protected ClientShSessionListener clientShSessionListener; protected ServerShSessionListener serverShSessionListener; protected IShMessageFactory messageFactory; //not used. protected StateChangeListener stateChangeListener; // Our magic -------------------------------------------------------------- protected ISessionFactory sessionFactory; protected ISessionDatasource sessionDataSource; protected IAppSessionDataFactory sessionDataFactory; protected long messageTimeout = 10000; // 10s default timeout protected static final long applicationId = 16777217; public ShSessionFactoryImpl(SessionFactory sessionFactory) { super(); this.sessionFactory = (ISessionFactory) sessionFactory; this.sessionDataSource = this.sessionFactory.getContainer().getAssemblerFacility() .getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.sessionDataSource .getDataFactory(IShSessionData.class); if (this.sessionDataFactory == null) { logger.debug("No factory for Sh Application data, using default/local."); this.sessionDataFactory = new ShLocalSessionDataFactory(); } } /** * @return the clientShSessionListener */ @Override public ClientShSessionListener getClientShSessionListener() { if (this.clientShSessionListener == null) { return this; } else { return clientShSessionListener; } } /** * @param clientShSessionListener the clientShSessionListener to set */ @Override public void setClientShSessionListener(ClientShSessionListener clientShSessionListener) { this.clientShSessionListener = clientShSessionListener; } /** * @return the serverShSessionListener */ @Override public ServerShSessionListener getServerShSessionListener() { if (this.serverShSessionListener == null) { return this; } else { return serverShSessionListener; } } /** * @param serverShSessionListener the serverShSessionListener to set */ @Override public void setServerShSessionListener(ServerShSessionListener serverShSessionListener) { this.serverShSessionListener = serverShSessionListener; } /** * @return the messageFactory */ @Override public IShMessageFactory getMessageFactory() { if (this.messageFactory == null) { return this; } else { return messageFactory; } } /** * @param messageFactory the messageFactory to set */ @Override public void setMessageFactory(IShMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @return the stateChangeListener */ @Override public StateChangeListener getStateChangeListener() { return stateChangeListener; } /** * @param stateChangeListener the stateChangeListener to set */ @Override public void setStateChangeListener(StateChangeListener stateChangeListener) { this.stateChangeListener = stateChangeListener; } // IAppSession ------------------------------------------------------------ /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionFactory#getNewSession(java.lang.String, java.lang.Class, * org.jdiameter.api.ApplicationId, java.lang.Object[]) */ @Override public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { try { // FIXME: add proper handling for SessionId if (aClass == ClientShSession.class) { ShClientSessionImpl clientSession = null; if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IShClientSessionData sessionData = (IShClientSessionData) this.sessionDataFactory .getAppSessionData(ClientShSession.class, sessionId); sessionData.setApplicationId(applicationId); clientSession = new ShClientSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientShSessionListener()); sessionDataSource.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); return clientSession; } else if (aClass == ServerShSession.class) { ShServerSessionImpl serverSession = null; if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IShServerSessionData sessionData = (IShServerSessionData) this.sessionDataFactory .getAppSessionData(ServerShSession.class, sessionId); sessionData.setApplicationId(applicationId); serverSession = new ShServerSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, getServerShSessionListener()); sessionDataSource.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); return serverSession; } else { throw new IllegalArgumentException( "Wrong session class: [" + aClass + "]. Supported[" + ClientShSession.class + "]"); } } catch (IllegalArgumentException iae) { throw iae; } catch (Exception e) { logger.error("Failure to obtain new Sh Session.", e); } return null; } @Override public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("Session-Id must not be null"); } if (!this.sessionDataSource.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ServerShSession.class) { IShServerSessionData sessionData = (IShServerSessionData) this.sessionDataFactory .getAppSessionData(ServerShSession.class, sessionId); appSession = new ShServerSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, getServerShSessionListener()); appSession.getSessions().get(0).setRequestListener((NetworkReqListener) appSession); } else if (aClass == ClientShSession.class) { IShClientSessionData sessionData = (IShClientSessionData) this.sessionDataFactory .getAppSessionData(ClientShSession.class, sessionId); appSession = new ShClientSessionImpl(sessionData, this.getMessageFactory(), sessionFactory, this.getClientShSessionListener()); appSession.getSessions().get(0).setRequestListener((NetworkReqListener) appSession); } else { throw new IllegalArgumentException("Wrong session class: " + aClass + ". Supported[" + ServerShSession.class + "," + ClientShSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new Sh Session.", e); } return appSession; } // Methods to handle default values for user listeners -------------------- @Override @SuppressWarnings("unchecked") public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter Sh SessionFactory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateChangeListener#stateChanged(java.lang.Object, java.lang.Enum, java.lang.Enum) */ @Override @SuppressWarnings("unchecked") public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter Sh SessionFactory :: stateChanged :: source[{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } // Message Handlers ------------------------------------------------------- /* * (non-Javadoc) * * @see org.jdiameter.api.sh.ClientShSessionListener#doOtherEvent(org.jdiameter.api.app.AppSession, * org.jdiameter.api.app.AppRequestEvent, org.jdiameter.api.app.AppAnswerEvent) */ @Override public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see org.jdiameter.api.sh.ClientShSessionListener#doProfileUpdateAnswerEvent(org.jdiameter.api.sh.ClientShSession, * org.jdiameter.api.sh.events.ProfileUpdateRequest, org.jdiameter.api.sh.events.ProfileUpdateAnswer) */ @Override public void doProfileUpdateAnswerEvent(ClientShSession session, ProfileUpdateRequest request, ProfileUpdateAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see org.jdiameter.api.sh.ClientShSessionListener#doPushNotificationRequestEvent( * org.jdiameter.api.sh.ClientShSession, org.jdiameter.api.sh.events.PushNotificationRequest) */ @Override public void doPushNotificationRequestEvent(ClientShSession session, PushNotificationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see * org.jdiameter.api.sh.ClientShSessionListener#doSubscribeNotificationsAnswerEvent(org.jdiameter.api.sh.ClientShSession, * org.jdiameter.api.sh.events.SubscribeNotificationsRequest, org.jdiameter.api.sh.events.SubscribeNotificationsAnswer) */ @Override public void doSubscribeNotificationsAnswerEvent(ClientShSession session, SubscribeNotificationsRequest request, SubscribeNotificationsAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see * org.jdiameter.api.sh.ClientShSessionListener#doUserDataAnswerEvent(org * .jdiameter.api.sh.ClientShSession, * org.jdiameter.api.sh.events.UserDataRequest, * org.jdiameter.api.sh.events.UserDataAnswer) */ @Override public void doUserDataAnswerEvent(ClientShSession session, UserDataRequest request, UserDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see * org.jdiameter.api.sh.ServerShSessionListener#doProfileUpdateRequestEvent * (org.jdiameter.api.sh.ServerShSession, * org.jdiameter.api.sh.events.ProfileUpdateRequest) */ @Override public void doProfileUpdateRequestEvent(ServerShSession session, ProfileUpdateRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see * org.jdiameter.api.sh.ServerShSessionListener#doPushNotificationAnswerEvent * (org.jdiameter.api.sh.ServerShSession, * org.jdiameter.api.sh.events.PushNotificationRequest, * org.jdiameter.api.sh.events.PushNotificationAnswer) */ @Override public void doPushNotificationAnswerEvent(ServerShSession session, PushNotificationRequest request, PushNotificationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @seeorg.jdiameter.api.sh.ServerShSessionListener# * doSubscribeNotificationsRequestEvent * (org.jdiameter.api.sh.ServerShSession, * org.jdiameter.api.sh.events.SubscribeNotificationsRequest) */ @Override public void doSubscribeNotificationsRequestEvent(ServerShSession session, SubscribeNotificationsRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see * org.jdiameter.api.sh.ServerShSessionListener#doUserDataRequestEvent(org * .jdiameter.api.sh.ServerShSession, * org.jdiameter.api.sh.events.UserDataRequest) */ @Override public void doUserDataRequestEvent(ServerShSession session, UserDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } // Message Factory ---------------------------------------------------------- @Override public AppAnswerEvent createProfileUpdateAnswer(Answer answer) { return new ProfileUpdateAnswerImpl(answer); } @Override public AppRequestEvent createProfileUpdateRequest(Request request) { return new ProfileUpdateRequestImpl(request); } @Override public AppAnswerEvent createPushNotificationAnswer(Answer answer) { return new PushNotificationAnswerImpl(answer); } @Override public AppRequestEvent createPushNotificationRequest(Request request) { return new PushNotificationRequestImpl(request); } @Override public AppAnswerEvent createSubscribeNotificationsAnswer(Answer answer) { return new SubscribeNotificationsAnswerImpl(answer); } @Override public AppRequestEvent createSubscribeNotificationsRequest(Request request) { return new SubscribeNotificationsRequestImpl(request); } @Override public AppAnswerEvent createUserDataAnswer(Answer answer) { return new UserDataAnswerImpl(answer); } @Override public AppRequestEvent createUserDataRequest(Request request) { return new UserDataRequestImpl(request); } @Override public long getApplicationId() { return applicationId; } @Override public long getMessageTimeout() { return messageTimeout; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/SubscribeNotificationsAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.sh.events.SubscribeNotificationsAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class SubscribeNotificationsAnswerImpl extends AppAnswerEventImpl implements SubscribeNotificationsAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public SubscribeNotificationsAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public SubscribeNotificationsAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public SubscribeNotificationsAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public SubscribeNotificationsAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/SubscribeNotificationsRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import org.jdiameter.api.Request; import org.jdiameter.api.sh.events.SubscribeNotificationsRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class SubscribeNotificationsRequestImpl extends AppRequestEventImpl implements SubscribeNotificationsRequest { private static final long serialVersionUID = 1L; public SubscribeNotificationsRequestImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/UserDataAnswerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.api.sh.events.UserDataAnswer; import org.jdiameter.common.impl.app.AppAnswerEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class UserDataAnswerImpl extends AppAnswerEventImpl implements UserDataAnswer { private static final long serialVersionUID = 1L; /** * @param answer */ public UserDataAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param vendorId * @param resultCode */ public UserDataAnswerImpl(Request request, long vendorId, long resultCode) { super(request, vendorId, resultCode); } /** * @param request * @param resultCode */ public UserDataAnswerImpl(Request request, long resultCode) { super(request, resultCode); } /** * @param request */ public UserDataAnswerImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/sh/UserDataRequestImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.app.sh; import org.jdiameter.api.Request; import org.jdiameter.api.sh.events.UserDataRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class UserDataRequestImpl extends AppRequestEventImpl implements UserDataRequest { private static final long serialVersionUID = 1L; public UserDataRequestImpl(Request request) { super(request); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/LocationReportAnswerImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slg; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.slg.events.LocationReportAnswer; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class LocationReportAnswerImpl extends AppRequestEventImpl implements LocationReportAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(LocationReportAnswerImpl.class); /** * @param answer */ public LocationReportAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public LocationReportAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } public Avp getResultCodeAvp() throws AvpDataException { return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/LocationReportRequestImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slg; import org.jdiameter.api.Message; import org.jdiameter.api.slg.events.LocationReportRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class LocationReportRequestImpl extends AppRequestEventImpl implements LocationReportRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(LocationReportRequestImpl.class); public LocationReportRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/ProvideLocationAnswerImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slg; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.slg.events.ProvideLocationAnswer; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class ProvideLocationAnswerImpl extends AppRequestEventImpl implements ProvideLocationAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(ProvideLocationRequestImpl.class); /** * @param answer */ public ProvideLocationAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public ProvideLocationAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } public Avp getResultCodeAvp() throws AvpDataException { return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/ProvideLocationRequestImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slg; import org.jdiameter.api.Message; import org.jdiameter.api.slg.events.ProvideLocationRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class ProvideLocationRequestImpl extends AppRequestEventImpl implements ProvideLocationRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(ProvideLocationRequestImpl.class); public ProvideLocationRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgLocalSessionDataFactory.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slg; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.slg.ClientSLgSession; import org.jdiameter.api.slg.ServerSLgSession; import org.jdiameter.client.impl.app.slg.ClientSLgSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.slg.ISLgSessionData; import org.jdiameter.server.impl.app.slg.ServerSLgSessionDataLocalImpl; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLgLocalSessionDataFactory implements IAppSessionDataFactory { public ISLgSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientSLgSession.class)) { ClientSLgSessionDataLocalImpl data = new ClientSLgSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerSLgSession.class)) { ServerSLgSessionDataLocalImpl data = new ServerSLgSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else { throw new IllegalArgumentException("Invalid Session Class: " + clazz.toString()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgLocalSessionDataImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slg; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.slg.ISLgSessionData; import org.jdiameter.common.api.app.slg.SLgSessionState; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLgLocalSessionDataImpl extends AppSessionDataLocalImpl implements ISLgSessionData { protected SLgSessionState state = SLgSessionState.IDLE; protected Request buffer; protected Serializable tsTimerId; public void setSLgSessionState(SLgSessionState state) { this.state = state; } public SLgSessionState getSLgSessionState() { return this.state; } public Serializable getTsTimerId() { return this.tsTimerId; } public void setTsTimerId(Serializable tid) { this.tsTimerId = tid; } public void setBuffer(Request buffer) { this.buffer = buffer; } public Request getBuffer() { return this.buffer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgSession.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slg; import java.io.Serializable; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.slg.ISLgMessageFactory; import org.jdiameter.common.api.app.slg.ISLgSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public abstract class SLgSession extends AppSessionImpl implements NetworkReqListener, StateMachine { public static final int _TX_TIMEOUT = 30 * 1000; protected Lock sendAndStateLock = new ReentrantLock(); @SuppressWarnings("rawtypes") protected transient List stateListeners = new CopyOnWriteArrayList(); protected transient ISLgMessageFactory messageFactory; protected static final String TIMER_NAME_MSG_TIMEOUT = "MSG_TIMEOUT"; protected ISLgSessionData sessionData; public SLgSession(ISessionFactory sf, ISLgSessionData sessionData) { super(sf, sessionData); this.sessionData = sessionData; } @SuppressWarnings("rawtypes") public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @SuppressWarnings("rawtypes") public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } public boolean isStateless() { return true; } @Override public boolean isReplicable() { return false; } protected void startMsgTimer() { try { sendAndStateLock.lock(); sessionData.setTsTimerId(super.timerFacility.schedule(getSessionId(), TIMER_NAME_MSG_TIMEOUT, _TX_TIMEOUT)); } finally { sendAndStateLock.unlock(); } } protected void cancelMsgTimer() { try { sendAndStateLock.lock(); final Serializable timerId = this.sessionData.getTsTimerId(); if (timerId == null) { return; } super.timerFacility.cancel(timerId); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } SLgSession other = (SLgSession) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgSessionFactoryImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slg; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.slg.ClientSLgSession; import org.jdiameter.api.slg.ClientSLgSessionListener; import org.jdiameter.api.slg.ServerSLgSession; import org.jdiameter.api.slg.ServerSLgSessionListener; import org.jdiameter.api.slg.events.LocationReportAnswer; import org.jdiameter.api.slg.events.LocationReportRequest; import org.jdiameter.api.slg.events.ProvideLocationAnswer; import org.jdiameter.api.slg.events.ProvideLocationRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.slg.IClientSLgSessionData; import org.jdiameter.client.impl.app.slg.SLgClientSessionImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.slg.ISLgMessageFactory; import org.jdiameter.common.api.app.slg.ISLgSessionData; import org.jdiameter.common.api.app.slg.ISLgSessionFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.slg.IServerSLgSessionData; import org.jdiameter.server.impl.app.slg.SLgServerSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLgSessionFactoryImpl implements ISLgSessionFactory, ServerSLgSessionListener, ClientSLgSessionListener, ISLgMessageFactory, StateChangeListener { private static final Logger logger = LoggerFactory.getLogger(SLgSessionFactoryImpl.class); protected ISessionFactory sessionFactory; protected ServerSLgSessionListener serverSessionListener; protected ClientSLgSessionListener clientSessionListener; protected ISLgMessageFactory messageFactory; protected StateChangeListener stateListener; protected ISessionDatasource iss; protected IAppSessionDataFactory sessionDataFactory; public SLgSessionFactoryImpl() { } public SLgSessionFactoryImpl(SessionFactory sessionFactory) { super(); init(sessionFactory); } public void init(SessionFactory sessionFactory) { this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(ISLgSessionData.class); } /** * @return the serverSessionListener */ public ServerSLgSessionListener getServerSessionListener() { return serverSessionListener != null ? serverSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ public void setServerSessionListener(ServerSLgSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the serverSessionListener */ public ClientSLgSessionListener getClientSessionListener() { return clientSessionListener != null ? clientSessionListener : this; } /** * @param clientSessionListener the clientSessionListener to set */ public void setClientSessionListener(ClientSLgSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the messageFactory */ public ISLgMessageFactory getMessageFactory() { return messageFactory != null ? messageFactory : this; } /** * @param messageFactory the messageFactory to set */ public void setMessageFactory(ISLgMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @return the stateListener */ public StateChangeListener getStateListener() { return stateListener != null ? stateListener : this; } /** * @param stateListener the stateListener to set */ public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ServerSLgSession.class) { IServerSLgSessionData sessionData = (IServerSLgSessionData) this.sessionDataFactory .getAppSessionData(ServerSLgSession.class, sessionId); SLgServerSessionImpl serverSession = new SLgServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else if (aClass == ClientSLgSession.class) { IClientSLgSessionData sessionData = (IClientSLgSessionData) this.sessionDataFactory .getAppSessionData(ClientSLgSession.class, sessionId); SLgClientSessionImpl clientSession = new SLgClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else { throw new IllegalArgumentException( "Wrong session class: " + aClass + ". Supported[" + ServerSLgSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new SLg Session.", e); } return appSession; } public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; try { if (aClass == ServerSLgSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerSLgSessionData sessionData = (IServerSLgSessionData) this.sessionDataFactory .getAppSessionData(ServerSLgSession.class, sessionId); sessionData.setApplicationId(applicationId); SLgServerSessionImpl serverSession = new SLgServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); iss.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else if (aClass == ClientSLgSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientSLgSessionData sessionData = (IClientSLgSessionData) this.sessionDataFactory .getAppSessionData(ClientSLgSession.class, sessionId); sessionData.setApplicationId(applicationId); SLgClientSessionImpl clientSession = new SLgClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else { throw new IllegalArgumentException( "Wrong session class: " + aClass + ". Supported[" + ServerSLgSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new SLg Session.", e); } return appSession; } public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter SLg Session Factory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } public long getApplicationId() { return 16777255; } public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter SLg Session Factory :: stateChanged :: Session, [{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } public ProvideLocationRequest createProvideLocationRequest(Request request) { return new ProvideLocationRequestImpl(request); } public ProvideLocationAnswer createProvideLocationAnswer(Answer answer) { return new ProvideLocationAnswerImpl(answer); } public void doProvideLocationRequestEvent(ServerSLgSession appSession, ProvideLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter SLg Session Factory :: doProvideLocationRequestEvent :: appSession[{}], Request[{}]", appSession, request); } public void doProvideLocationAnswerEvent(ClientSLgSession appSession, ProvideLocationRequest request, ProvideLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter SLg Session Factory :: doProvideLocationAnswerEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } public LocationReportRequest createLocationReportRequest(Request request) { return new LocationReportRequestImpl(request); } public LocationReportAnswer createLocationReportAnswer(Answer answer) { return new LocationReportAnswerImpl(answer); } public void doLocationReportRequestEvent(ClientSLgSession appSession, LocationReportRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter SLg Session Factory :: doLocationReportRequestEvent :: appSession[{}], Request[{}]", appSession, request); } public void doLocationReportAnswerEvent(ServerSLgSession appSession, LocationReportRequest request, LocationReportAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter SLg Session Factory :: doLocationReportAnswerEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter SLg Session Factory :: doOtherEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/LCSRoutingInfoAnswerImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slh; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class LCSRoutingInfoAnswerImpl extends AppRequestEventImpl implements LCSRoutingInfoAnswer { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(LCSRoutingInfoAnswer.class); /** * @param answer */ public LCSRoutingInfoAnswerImpl(Answer answer) { super(answer); } /** * @param request * @param resultCode */ public LCSRoutingInfoAnswerImpl(Request request, long resultCode) { super(request.createAnswer(resultCode)); } public Avp getResultCodeAvp() throws AvpDataException { return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/LCSRoutingInfoRequestImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slh; import org.jdiameter.api.Message; import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class LCSRoutingInfoRequestImpl extends AppRequestEventImpl implements LCSRoutingInfoRequest { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(LCSRoutingInfoRequestImpl.class); public LCSRoutingInfoRequestImpl(Message message) { super(message); message.setRequest(true); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhLocalSessionDataFactory.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slh; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.slh.ClientSLhSession; import org.jdiameter.api.slh.ServerSLhSession; import org.jdiameter.client.impl.app.slh.ClientSLhSessionDataLocalImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.slh.ISLhSessionData; import org.jdiameter.server.impl.app.slh.ServerSLhSessionDataLocalImpl; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLhLocalSessionDataFactory implements IAppSessionDataFactory { public ISLhSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientSLhSession.class)) { ClientSLhSessionDataLocalImpl data = new ClientSLhSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else if (clazz.equals(ServerSLhSession.class)) { ServerSLhSessionDataLocalImpl data = new ServerSLhSessionDataLocalImpl(); data.setSessionId(sessionId); return data; } else { throw new IllegalArgumentException("Invalid Session Class: " + clazz.toString()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhLocalSessionDataImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slh; import java.io.Serializable; import org.jdiameter.api.Request; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.slh.ISLhSessionData; import org.jdiameter.common.api.app.slh.SLhSessionState; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLhLocalSessionDataImpl extends AppSessionDataLocalImpl implements ISLhSessionData { protected SLhSessionState state = SLhSessionState.IDLE; protected Request buffer; protected Serializable tsTimerId; public void setSLhSessionState(SLhSessionState state) { this.state = state; } public SLhSessionState getSLhSessionState() { return this.state; } public Serializable getTsTimerId() { return this.tsTimerId; } public void setTsTimerId(Serializable tid) { this.tsTimerId = tid; } public void setBuffer(Request buffer) { this.buffer = buffer; } public Request getBuffer() { return this.buffer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhSession.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slh; import java.io.Serializable; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateMachine; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.slh.ISLhMessageFactory; import org.jdiameter.common.api.app.slh.ISLhSessionData; import org.jdiameter.common.impl.app.AppSessionImpl; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public abstract class SLhSession extends AppSessionImpl implements NetworkReqListener, StateMachine { public static final int _TX_TIMEOUT = 30 * 1000; protected Lock sendAndStateLock = new ReentrantLock(); @SuppressWarnings("rawtypes") protected transient List stateListeners = new CopyOnWriteArrayList(); protected transient ISLhMessageFactory messageFactory; protected static final String TIMER_NAME_MSG_TIMEOUT = "MSG_TIMEOUT"; protected ISLhSessionData sessionData; public SLhSession(ISessionFactory sf, ISLhSessionData sessionData) { super(sf, sessionData); this.sessionData = sessionData; } @SuppressWarnings("rawtypes") public void addStateChangeNotification(StateChangeListener listener) { if (!stateListeners.contains(listener)) { stateListeners.add(listener); } } @SuppressWarnings("rawtypes") public void removeStateChangeNotification(StateChangeListener listener) { stateListeners.remove(listener); } public boolean isStateless() { return true; } @Override public boolean isReplicable() { return false; } protected void startMsgTimer() { try { sendAndStateLock.lock(); sessionData.setTsTimerId(super.timerFacility.schedule(getSessionId(), TIMER_NAME_MSG_TIMEOUT, _TX_TIMEOUT)); } finally { sendAndStateLock.unlock(); } } protected void cancelMsgTimer() { try { sendAndStateLock.lock(); final Serializable timerId = this.sessionData.getTsTimerId(); if (timerId == null) { return; } super.timerFacility.cancel(timerId); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } SLhSession other = (SLhSession) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhSessionFactoryImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.common.impl.app.slh; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.slh.ClientSLhSession; import org.jdiameter.api.slh.ClientSLhSessionListener; import org.jdiameter.api.slh.ServerSLhSession; import org.jdiameter.api.slh.ServerSLhSessionListener; import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.impl.app.slh.IClientSLhSessionData; import org.jdiameter.client.impl.app.slh.SLhClientSessionImpl; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.slh.ISLhMessageFactory; import org.jdiameter.common.api.app.slh.ISLhSessionData; import org.jdiameter.common.api.app.slh.ISLhSessionFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.server.impl.app.slh.IServerSLhSessionData; import org.jdiameter.server.impl.app.slh.SLhServerSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLhSessionFactoryImpl implements ISLhSessionFactory, ServerSLhSessionListener, ClientSLhSessionListener, ISLhMessageFactory, StateChangeListener { private static final Logger logger = LoggerFactory.getLogger(SLhSessionFactoryImpl.class); protected ISessionFactory sessionFactory; protected ServerSLhSessionListener serverSessionListener; protected ClientSLhSessionListener clientSessionListener; protected ISLhMessageFactory messageFactory; protected StateChangeListener stateListener; protected ISessionDatasource iss; protected IAppSessionDataFactory sessionDataFactory; public SLhSessionFactoryImpl() { } ; public SLhSessionFactoryImpl(SessionFactory sessionFactory) { super(); init(sessionFactory); } public void init(SessionFactory sessionFactory) { this.sessionFactory = (ISessionFactory) sessionFactory; this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(ISLhSessionData.class); } /** * @return the serverSessionListener */ public ServerSLhSessionListener getServerSessionListener() { return serverSessionListener != null ? serverSessionListener : this; } /** * @param serverSessionListener the serverSessionListener to set */ public void setServerSessionListener(ServerSLhSessionListener serverSessionListener) { this.serverSessionListener = serverSessionListener; } /** * @return the serverSessionListener */ public ClientSLhSessionListener getClientSessionListener() { return clientSessionListener != null ? clientSessionListener : this; } /** * @param clientSessionListener the clientSessionListener to set */ public void setClientSessionListener(ClientSLhSessionListener clientSessionListener) { this.clientSessionListener = clientSessionListener; } /** * @return the messageFactory */ public ISLhMessageFactory getMessageFactory() { return messageFactory != null ? messageFactory : this; } /** * @param messageFactory the messageFactory to set */ public void setMessageFactory(ISLhMessageFactory messageFactory) { this.messageFactory = messageFactory; } /** * @return the stateListener */ public StateChangeListener getStateListener() { return stateListener != null ? stateListener : this; } /** * @param stateListener the stateListener to set */ public void setStateListener(StateChangeListener stateListener) { this.stateListener = stateListener; } public AppSession getSession(String sessionId, Class aClass) { if (sessionId == null) { throw new IllegalArgumentException("SessionId must not be null"); } if (!this.iss.exists(sessionId)) { return null; } AppSession appSession = null; try { if (aClass == ServerSLhSession.class) { IServerSLhSessionData sessionData = (IServerSLhSessionData) this.sessionDataFactory .getAppSessionData(ServerSLhSession.class, sessionId); SLhServerSessionImpl serverSession = new SLhServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else if (aClass == ClientSLhSession.class) { IClientSLhSessionData sessionData = (IClientSLhSessionData) this.sessionDataFactory .getAppSessionData(ClientSLhSession.class, sessionId); SLhClientSessionImpl clientSession = new SLhClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else { throw new IllegalArgumentException( "Wrong session class: " + aClass + ". Supported[" + ServerSLhSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new SLh Session.", e); } return appSession; } public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { AppSession appSession = null; try { if (aClass == ServerSLhSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IServerSLhSessionData sessionData = (IServerSLhSessionData) this.sessionDataFactory .getAppSessionData(ServerSLhSession.class, sessionId); sessionData.setApplicationId(applicationId); SLhServerSessionImpl serverSession = new SLhServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); iss.addSession(serverSession); serverSession.getSessions().get(0).setRequestListener(serverSession); appSession = serverSession; } else if (aClass == ClientSLhSession.class) { if (sessionId == null) { if (args != null && args.length > 0 && args[0] instanceof Request) { Request request = (Request) args[0]; sessionId = request.getSessionId(); } else { sessionId = this.sessionFactory.getSessionId(); } } IClientSLhSessionData sessionData = (IClientSLhSessionData) this.sessionDataFactory .getAppSessionData(ClientSLhSession.class, sessionId); sessionData.setApplicationId(applicationId); SLhClientSessionImpl clientSession = new SLhClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); iss.addSession(clientSession); clientSession.getSessions().get(0).setRequestListener(clientSession); appSession = clientSession; } else { throw new IllegalArgumentException( "Wrong session class: " + aClass + ". Supported[" + ServerSLhSession.class + "]"); } } catch (Exception e) { logger.error("Failure to obtain new SLh Session.", e); } return appSession; } public void stateChanged(Enum oldState, Enum newState) { logger.info("Diameter SLh Session Factory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); } public long getApplicationId() { return 16777291; } public void stateChanged(AppSession source, Enum oldState, Enum newState) { logger.info("Diameter SLh Session Factory :: stateChanged :: Session, [{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); } public LCSRoutingInfoAnswer createLCSRoutingInfoAnswer(Answer answer) { return new LCSRoutingInfoAnswerImpl(answer); } public LCSRoutingInfoRequest createLCSRoutingInfoRequest(Request request) { return new LCSRoutingInfoRequestImpl(request); } public void doLCSRoutingInfoRequestEvent(ServerSLhSession appSession, LCSRoutingInfoRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter SLh Session Factory :: doLCSRoutingInfoRequestEvent :: appSession[{}], Request[{}]", appSession, request); } public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info("Diameter SLh Session Factory :: doOtherEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } public void doLCSRoutingInfoAnswerEvent(ClientSLhSession appSession, LCSRoutingInfoRequest request, LCSRoutingInfoAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { logger.info( "Diameter SLh Session Factory :: doLCSRoutingInfoAnswerEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/concurrent/AbstractTask.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.concurrent; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticRecord; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ abstract class AbstractTask { protected L parentTask; protected long createdTime = System.nanoTime(); protected IStatistic statistic; protected IStatisticRecord execTimeSumm; protected IStatisticRecord execTimeCount; protected IStatisticRecord waitTimeSumm; protected IStatisticRecord waitTimeCount; AbstractTask(L task, final IStatistic statistic, IStatisticRecord... statisticRecords) { this.parentTask = task; execTimeSumm = statisticRecords[0]; execTimeCount = statisticRecords[1]; waitTimeSumm = statisticRecords[2]; waitTimeCount = statisticRecords[3]; this.statistic = statistic; } protected IStatisticRecord getCounter(IStatisticRecord.Counters counter) { return statistic.getRecordByName(counter.name()); } protected void updateTimeStatistic(long time, long waitTime) { if (statistic.isEnabled()) { execTimeSumm.inc((System.nanoTime() - time) / 999999); execTimeCount.inc(); waitTimeSumm.inc(waitTime / 999999); waitTimeCount.inc(); } } @Override @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") public boolean equals(Object o) { return this == o || parentTask.equals(o); } @Override public int hashCode() { return parentTask.hashCode(); } public static class AverageValueHolder implements IStatisticRecord.ValueHolder { private IStatistic statistic; private IStatisticRecord.Counters counter; AverageValueHolder(IStatistic statistic, IStatisticRecord.Counters counter) { this.statistic = statistic; this.counter = counter; } public double getValueAsDouble() { IStatisticRecord record = statistic.getRecordByName(counter.name()); if (statistic.isEnabled() && (record.getChilds().length == 2 || record.getChilds()[1].getValueAsLong() != 0)) { long count = record.getChilds()[1].getValueAsLong(); return ((float) record.getChilds()[0].getValueAsLong()) / ((float) (count != 0 ? count : 1)); } else { return 0; } } @Override public String getValueAsString() { return String.valueOf(getValueAsDouble()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/concurrent/BaseThreadFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.concurrent; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class BaseThreadFactory implements ThreadFactory { private static final Logger log = LoggerFactory.getLogger(BaseThreadFactory.class); public static final String ENTITY_NAME = "ThreadPool"; private ExecutorService threadPoolExecutor; BaseThreadFactory(boolean useVirtualThreads) { if (useVirtualThreads) { log.info("Using virtual thread pool executor"); this.threadPoolExecutor = Executors.newVirtualThreadPerTaskExecutor(); } else { log.info("Using cached thread pool executor"); this.threadPoolExecutor = Executors.newCachedThreadPool(); } } public ExecutorService getThreadPool() { return this.threadPoolExecutor; } @Override public Thread newThread(Runnable runnable) { return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/concurrent/CommonScheduledExecutorService.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.concurrent; import static org.jdiameter.common.api.statistic.IStatistic.Groups.ScheduledExecService; import static org.jdiameter.common.api.statistic.IStatisticRecord.Counters.*; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.jdiameter.api.Configuration; import org.jdiameter.client.impl.helpers.Parameters; import org.jdiameter.common.api.concurrent.IConcurrentEntityFactory; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class CommonScheduledExecutorService extends ScheduledThreadPoolExecutor { private IStatistic statistic; private IConcurrentEntityFactory entityFactory; private IStatisticRecord execTimeSumm; private IStatisticRecord execTimeCount; private IStatisticRecord waitTimeSumm; private IStatisticRecord waitTimeCount; private IStatisticManager statisticFactory; CommonScheduledExecutorService(String name, Configuration config, final IConcurrentEntityFactory entityFactory, IStatisticManager statisticFactory) { super(config == null ? (Integer) Parameters.ConcurrentEntityPoolSize.defValue() : config.getIntValue(Parameters.ConcurrentEntityPoolSize.ordinal(), (Integer) Parameters.ConcurrentEntityPoolSize.defValue())); this.statisticFactory = statisticFactory; this.entityFactory = entityFactory; final IStatisticRecord rejectedCount = statisticFactory.newCounterRecord(RejectedTasks); execTimeSumm = statisticFactory.newCounterRecord("TimeSumm", "TimeSumm"); execTimeCount = statisticFactory.newCounterRecord("TimeCount", "TimeCount"); waitTimeSumm = statisticFactory.newCounterRecord("TimeSumm", "TimeSumm"); waitTimeCount = statisticFactory.newCounterRecord("TimeCount", "TimeCount"); //XXX: YYY: no need to remove? it lives as long stack does. statistic = statisticFactory.newStatistic(name, ScheduledExecService, rejectedCount); final IStatisticRecord execTimeCounter = statisticFactory.newCounterRecord(IStatisticRecord.Counters.ExecTimeTask, new AbstractTask.AverageValueHolder( statistic, IStatisticRecord.Counters.ExecTimeTask), execTimeSumm, execTimeCount); final IStatisticRecord waitTimeCounter = statisticFactory.newCounterRecord(IStatisticRecord.Counters.WaitTimeTask, new AbstractTask.AverageValueHolder( statistic, IStatisticRecord.Counters.WaitTimeTask), waitTimeSumm, waitTimeCount); statistic.appendCounter(statisticFactory.newCounterRecord(WorkingThread), statisticFactory.newCounterRecord(CanceledTasks), statisticFactory.newCounterRecord(BrokenTasks), execTimeCounter, waitTimeCounter, statisticFactory.newCounterRecord(WaitTimeTask)); super.setRejectedExecutionHandler(entityFactory.newRejectedExecutionHandler(rejectedCount)); } @Override public ScheduledFuture schedule(Runnable runnable, long delay, TimeUnit unit) { return super.schedule(this.entityFactory.newDefaultRunnable(runnable, statistic, execTimeSumm, execTimeCount, waitTimeSumm, waitTimeCount), delay, unit); } @Override public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { return super.schedule(this.entityFactory.newDefaultCallable(callable, statistic, execTimeSumm, execTimeCount, waitTimeSumm, waitTimeCount), delay, unit); } @Override public ScheduledFuture scheduleAtFixedRate(Runnable runnable, long initialDelay, long period, TimeUnit unit) { return super.scheduleAtFixedRate( this.entityFactory.newDefaultRunnable(runnable, statistic, execTimeSumm, execTimeCount, waitTimeSumm, waitTimeCount), initialDelay, period, unit); } public IStatistic getStatistic() { return statistic; } @Override public void shutdown() { this.statisticFactory.removeStatistic(statistic); super.shutdown(); } @Override public List shutdownNow() { this.statisticFactory.removeStatistic(statistic); return super.shutdownNow(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/concurrent/ConcurrentEntityFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import org.jdiameter.api.Configuration; import org.jdiameter.client.impl.helpers.Parameters; import org.jdiameter.common.api.concurrent.IConcurrentEntityFactory; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticRecord; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party libs public class ConcurrentEntityFactory implements IConcurrentEntityFactory { private Configuration config; // TODO: get rid of that? public ConcurrentEntityFactory(Configuration config) { this.config = config; } @Override public ThreadFactory newThreadFactory() { boolean useVirtualThreads = config.getBooleanValue(Parameters.UseVirtualThreads.ordinal(), (Boolean) Parameters.UseVirtualThreads.defValue()); return new BaseThreadFactory(useVirtualThreads); } @Override public RejectedExecutionHandler newRejectedExecutionHandler(IStatisticRecord rejectedCount) { return new DefaultRejectedExecutionHandler(rejectedCount); } @Override public Callable newDefaultCallable(Callable runnable, IStatistic statistic, IStatisticRecord... statisticRecords) { return new DefaultCallable(runnable, statistic, statisticRecords); } @Override public Runnable newDefaultRunnable(Runnable runnable, IStatistic statistic, IStatisticRecord... statisticRecords) { return new DefaultRunnable(runnable, statistic, statisticRecords); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/concurrent/ConcurrentFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.concurrent; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; import org.jdiameter.api.Configuration; import org.jdiameter.client.impl.helpers.Parameters; import org.jdiameter.common.api.concurrent.IConcurrentEntityFactory; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ConcurrentFactory implements IConcurrentFactory { private BaseThreadFactory threadFactory; private Map scheduledExecutorServices; private Configuration[] config; private IStatisticManager statisticFactory; private IStatistic statistic; private IConcurrentEntityFactory entityFactory; public ConcurrentFactory(Configuration config, IStatisticManager statisticFactory, IConcurrentEntityFactory entityFactory) { this.config = config.getChildren(Parameters.Concurrent.ordinal()); this.entityFactory = entityFactory; Configuration dgConfig = getConfigByName(BaseThreadFactory.ENTITY_NAME); String defThreadGroupName = dgConfig != null ? dgConfig.getStringValue(Parameters.ConcurrentEntityDescription.ordinal(), (String) Parameters.ConcurrentEntityDescription.defValue()) : (String) Parameters.ConcurrentEntityDescription.defValue(); threadFactory = (BaseThreadFactory) entityFactory.newThreadFactory(); scheduledExecutorServices = new ConcurrentHashMap(); IStatisticRecord threadCount = statisticFactory.newCounterRecord( IStatisticRecord.Counters.ConcurrentThread, new IStatisticRecord.IntegerValueHolder() { @Override public String getValueAsString() { return getValueAsInt() + ""; } @Override public int getValueAsInt() { return ((ThreadPoolExecutor) getThreadPool()).getActiveCount(); } }); //TODO: make use of this stat.... IStatisticRecord schedExeServiceCount = statisticFactory.newCounterRecord( IStatisticRecord.Counters.ConcurrentScheduledExecutedServices, new IStatisticRecord.IntegerValueHolder() { @Override public String getValueAsString() { return getValueAsInt() + ""; } @Override public int getValueAsInt() { return scheduledExecutorServices.size(); } }); statistic = statisticFactory.newStatistic("scheduled", IStatistic.Groups.Concurrent, threadCount, schedExeServiceCount); this.statisticFactory = statisticFactory; } /** * fetch configuration for executor * * @param name * @return */ private Configuration getConfigByName(String name) { if (config != null) { for (Configuration c : config) { if (c != null && c.getStringValue(Parameters.ConcurrentEntityName.ordinal(), "").equals(name)) { return c; } } } return null; } @Override public ExecutorService getThreadPool() { return threadFactory.getThreadPool(); } @Override public ScheduledExecutorService getScheduledExecutorService(String name) { CommonScheduledExecutorService service = null; if (!scheduledExecutorServices.containsKey(name)) { //ZhixiaoLuo: fix StatisticManagerImpl.IllegalArgumentException if 2 sessions try to get ApplicationSession service synchronized (ConcurrentFactory.class) { if (!scheduledExecutorServices.containsKey(name)) { service = new CommonScheduledExecutorService(name, getConfigByName(name), this.entityFactory, statisticFactory); scheduledExecutorServices.put(name, service); } } } else { service = scheduledExecutorServices.get(name); } return service; } @Override public Collection getScheduledExecutorServices() { List external = new ArrayList(scheduledExecutorServices.values()); return external; } @Override public void shutdownNow(ScheduledExecutorService service) { for (String name : scheduledExecutorServices.keySet()) { ExecutorService e = scheduledExecutorServices.get(name); if (e == service) { e.shutdownNow(); scheduledExecutorServices.remove(name); break; } } } @Override public IStatistic getStatistic() { return statistic; } @Override public List getStatistics() { List statistics = new ArrayList(); for (CommonScheduledExecutorService e : scheduledExecutorServices.values()) { statistics.add(e.getStatistic()); } return statistics; } @Override public void shutdownAllNow() { for (String name : scheduledExecutorServices.keySet()) { ExecutorService e = scheduledExecutorServices.remove(name); e.shutdownNow(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/concurrent/DefaultCallable.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.concurrent; import static org.jdiameter.common.api.statistic.IStatisticRecord.Counters.*; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticRecord; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ class DefaultCallable extends AbstractTask> implements Callable { DefaultCallable(Callable task, IStatistic statistic, IStatisticRecord... statisticRecords) { super(task, statistic, statisticRecords); } @Override public L call() throws Exception { long time = 0; if (statistic.isEnabled()) { getCounter(WorkingThread).inc(); time = System.nanoTime(); } try { return parentTask.call(); } catch (CancellationException e) { if (statistic.isEnabled()) { getCounter(CanceledTasks).inc(); } throw e; } catch (Exception e) { if (statistic.isEnabled()) { getCounter(BrokenTasks).inc(); } throw e; } finally { if (statistic.isEnabled()) { updateTimeStatistic(time, time - createdTime); getCounter(WorkingThread).dec(); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/concurrent/DefaultRejectedExecutionHandler.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.concurrent; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ class DefaultRejectedExecutionHandler implements RejectedExecutionHandler { private static final Logger log = LoggerFactory.getLogger(DefaultRejectedExecutionHandler.class); private IStatisticRecord rejectedCount; /** * @param rejectedCount */ DefaultRejectedExecutionHandler(IStatisticRecord rejectedCount) { this.rejectedCount = rejectedCount; } @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { log.debug("Task rejected {}", r); if (rejectedCount.isEnabled()) { rejectedCount.inc(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/concurrent/DefaultRunnable.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.concurrent; import static org.jdiameter.common.api.statistic.IStatisticRecord.Counters.BrokenTasks; import static org.jdiameter.common.api.statistic.IStatisticRecord.Counters.WorkingThread; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticRecord; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ class DefaultRunnable extends AbstractTask implements Runnable { DefaultRunnable(Runnable task, IStatistic statistic, IStatisticRecord... statisticRecords) { super(task, statistic, statisticRecords); } @Override public void run() { if (getCounter(WorkingThread) != null) { getCounter(WorkingThread).inc(); } long time = System.nanoTime(); try { parentTask.run(); } catch (RuntimeException e) { if (getCounter(BrokenTasks) != null) { getCounter(BrokenTasks).inc(); } throw e; } finally { updateTimeStatistic(time, time - createdTime); if (getCounter(WorkingThread) != null) { getCounter(WorkingThread).dec(); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/controller/AbstractPeer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.controller; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Peer; import org.jdiameter.api.URI; import org.jdiameter.client.impl.helpers.UIDGenerator; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AbstractPeer implements Comparable { private static final Logger logger = LoggerFactory.getLogger(AbstractPeer.class); public static final int INT_COMMON_APP_ID = 0xffffffff; protected static UIDGenerator uid = new UIDGenerator(); // Statistic protected IStatistic statistic; protected List perSecondRecords = new ArrayList(); protected URI uri; protected IStatisticManager statisticFactory; //Added locks to make statistics creation and removal thread safe private Lock statisticsLock = new ReentrantLock(); public AbstractPeer(URI uri, IStatisticManager statisticFactory) { this.uri = uri; this.statisticFactory = statisticFactory; } protected void createPeerStatistics() { logger.debug("Creating Peer Statistics for URI {}", this.uri); // PCB - Added locking around this so that the stats cannot be attempted // to be initialized twice by 2 threads entering this function at the same time try { statisticsLock.lock(); if (this.statistic != null) { return; } String uriString = uri == null ? "local" : uri.toString(); IStatisticRecord appGenRequestCounter = statisticFactory.newCounterRecord(IStatisticRecord.Counters.AppGenRequest); IStatisticRecord appGenCPSRequestCounter = statisticFactory.newPerSecondCounterRecord(uriString, IStatisticRecord.Counters.AppGenRequestPerSecond, appGenRequestCounter); IStatisticRecord appGenRejectedRequestCounter = statisticFactory .newCounterRecord(IStatisticRecord.Counters.AppGenRejectedRequest); perSecondRecords.add(appGenCPSRequestCounter); IStatisticRecord appGenResponseCounter = statisticFactory .newCounterRecord(IStatisticRecord.Counters.AppGenResponse); IStatisticRecord appGenCPSResponseCounter = statisticFactory.newPerSecondCounterRecord(uriString, IStatisticRecord.Counters.AppGenResponsePerSecond, appGenResponseCounter); IStatisticRecord appGenRejectedResponseCounter = statisticFactory .newCounterRecord(IStatisticRecord.Counters.AppGenRejectedResponse); perSecondRecords.add(appGenCPSResponseCounter); IStatisticRecord netGenRequestCounter = statisticFactory.newCounterRecord(IStatisticRecord.Counters.NetGenRequest); IStatisticRecord netGenCPSRequestCounter = statisticFactory.newPerSecondCounterRecord(uriString, IStatisticRecord.Counters.NetGenRequestPerSecond, netGenRequestCounter); IStatisticRecord netGenRejectedRequestCounter = statisticFactory .newCounterRecord(IStatisticRecord.Counters.NetGenRejectedRequest); perSecondRecords.add(netGenCPSRequestCounter); IStatisticRecord netGenResponseCounter = statisticFactory .newCounterRecord(IStatisticRecord.Counters.NetGenResponse); IStatisticRecord netGenCPSResponseCounter = statisticFactory.newPerSecondCounterRecord(uriString, IStatisticRecord.Counters.NetGenResponsePerSecond, netGenResponseCounter); IStatisticRecord netGenRejectedResponseCounter = statisticFactory .newCounterRecord(IStatisticRecord.Counters.NetGenRejectedResponse); perSecondRecords.add(netGenCPSResponseCounter); IStatisticRecord sysGenResponseCounter = statisticFactory .newCounterRecord(IStatisticRecord.Counters.SysGenResponse); this.statistic = statisticFactory.newStatistic(uriString, IStatistic.Groups.Peer, appGenRequestCounter, appGenCPSRequestCounter, appGenRejectedRequestCounter, appGenResponseCounter, appGenCPSResponseCounter, appGenRejectedResponseCounter, netGenRequestCounter, netGenCPSRequestCounter, netGenRejectedRequestCounter, netGenResponseCounter, netGenCPSResponseCounter, netGenRejectedResponseCounter, sysGenResponseCounter); } finally { logger.debug("Completed creating Peer Statistics for URI {}: {}", this.uri, this.statistic); if (this.statistic == null) { logger.warn("Failed to create Peer Statistics for URI {}, creating dummy and setting to disabled", this.uri); this.statistic = statisticFactory.newStatistic("local", IStatistic.Groups.Peer); this.statistic.enable(false); } statisticsLock.unlock(); } } protected void removePeerStatistics() { logger.debug("Removing Peer Statistics for URI {}", this.uri); //RG edited this to make removal of peer stats thread safe try { statisticsLock.lock(); if (this.statistic == null) { return; } for (IStatisticRecord rec : this.perSecondRecords) { this.statisticFactory.removePerSecondCounterRecord(rec); } this.statisticFactory.removeStatistic(this.statistic); this.perSecondRecords.clear(); this.statistic = null; } finally { logger.debug("Completed removing Peer Statistics for URI {}: {}", this.uri, this.statistic); statisticsLock.unlock(); } } @Override public int compareTo(Peer o) { return uri.compareTo(o.getUri()); } /** * @throws IllegalDiameterStateException * @throws InternalException */ protected void disconnect(int disconnectCause) throws InternalException, IllegalDiameterStateException { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/LocalDataSource.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.data; import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; import org.jdiameter.api.BaseSession; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.ISession; import org.jdiameter.common.api.app.IAppSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.acc.IAccSessionData; import org.jdiameter.common.api.app.auth.IAuthSessionData; import org.jdiameter.common.api.app.cca.ICCASessionData; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; import org.jdiameter.common.api.app.gx.IGxSessionData; import org.jdiameter.common.api.app.rf.IRfSessionData; import org.jdiameter.common.api.app.ro.IRoSessionData; import org.jdiameter.common.api.app.rx.IRxSessionData; import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.common.api.app.s6a.IS6aSessionData; import org.jdiameter.common.api.app.sh.IShSessionData; import org.jdiameter.common.api.app.slg.ISLgSessionData; import org.jdiameter.common.api.app.slh.ISLhSessionData; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.acc.AccLocalSessionDataFactory; import org.jdiameter.common.impl.app.auth.AuthLocalSessionDataFactory; import org.jdiameter.common.impl.app.cca.CCALocalSessionDataFactory; import org.jdiameter.common.impl.app.cxdx.CxDxLocalSessionDataFactory; import org.jdiameter.common.impl.app.gx.GxLocalSessionDataFactory; import org.jdiameter.common.impl.app.rf.RfLocalSessionDataFactory; import org.jdiameter.common.impl.app.ro.RoLocalSessionDataFactory; import org.jdiameter.common.impl.app.rx.RxLocalSessionDataFactory; import org.jdiameter.common.impl.app.s13.S13LocalSessionDataFactory; import org.jdiameter.common.impl.app.s6a.S6aLocalSessionDataFactory; import org.jdiameter.common.impl.app.sh.ShLocalSessionDataFactory; import org.jdiameter.common.impl.app.slg.SLgLocalSessionDataFactory; import org.jdiameter.common.impl.app.slh.SLhLocalSessionDataFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Local implementation of session datasource for {@link ISessionDatasource} * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class LocalDataSource implements ISessionDatasource { //provided by impl, no way to change that, no conf! :) protected HashMap, IAppSessionDataFactory> appSessionDataFactories = new HashMap, IAppSessionDataFactory>(); private ConcurrentHashMap sessionIdToEntry = new ConcurrentHashMap(); private static final Logger logger = LoggerFactory.getLogger(LocalDataSource.class); public LocalDataSource() { appSessionDataFactories.put(ICCASessionData.class, new CCALocalSessionDataFactory()); appSessionDataFactories.put(IRoSessionData.class, new RoLocalSessionDataFactory()); appSessionDataFactories.put(IRfSessionData.class, new RfLocalSessionDataFactory()); appSessionDataFactories.put(IGxSessionData.class, new GxLocalSessionDataFactory()); appSessionDataFactories.put(IAccSessionData.class, new AccLocalSessionDataFactory()); appSessionDataFactories.put(IAuthSessionData.class, new AuthLocalSessionDataFactory()); appSessionDataFactories.put(IShSessionData.class, new ShLocalSessionDataFactory()); appSessionDataFactories.put(ICxDxSessionData.class, new CxDxLocalSessionDataFactory()); appSessionDataFactories.put(IRxSessionData.class, new RxLocalSessionDataFactory()); appSessionDataFactories.put(IS6aSessionData.class, new S6aLocalSessionDataFactory()); appSessionDataFactories.put(IS13SessionData.class, new S13LocalSessionDataFactory()); appSessionDataFactories.put(ISLhSessionData.class, new SLhLocalSessionDataFactory()); appSessionDataFactories.put(ISLgSessionData.class, new SLgLocalSessionDataFactory()); } public LocalDataSource(IContainer container) { this(); } @Override public boolean exists(String sessionId) { return this.sessionIdToEntry.containsKey(sessionId); } @Override public void setSessionListener(String sessionId, NetworkReqListener data) { logger.debug("setSessionListener({}, {})", sessionId, data); SessionEntry se = sessionIdToEntry.get(sessionId); if (se != null) { se.listener = data; } else { throw new IllegalArgumentException("No Session entry for id: " + sessionId); } } @Override public NetworkReqListener getSessionListener(String sessionId) { SessionEntry se = sessionIdToEntry.get(sessionId); logger.debug("getSessionListener({}) => {}", sessionId, se); return se != null ? se.listener : null; } @Override public NetworkReqListener removeSessionListener(String sessionId) { SessionEntry se = sessionIdToEntry.get(sessionId); logger.debug("removeSessionListener({}) => {}", sessionId, se); if (se != null) { NetworkReqListener lst = se.listener; se.listener = null; return lst; } else { return null; } } @Override public void addSession(BaseSession session) { logger.debug("addSession({})", session); SessionEntry se = null; String sessionId = session.getSessionId(); //FIXME: check here replicable vs not replicable? if (this.sessionIdToEntry.containsKey(sessionId)) { se = this.sessionIdToEntry.get(sessionId); if (!(se.session instanceof ISession) || se.session.isReplicable()) { //must be not replicable so we can "overwrite" throw new IllegalArgumentException("Sessin with id: " + sessionId + ", already exists!"); } else { this.sessionIdToEntry.put(sessionId, se); } } else { se = new SessionEntry(); } se.session = session; this.sessionIdToEntry.put(session.getSessionId(), se); } @Override public BaseSession getSession(String sessionId) { SessionEntry se = sessionIdToEntry.get(sessionId); logger.debug("getSession({}) => {}", sessionId, se); return se != null ? se.session : null; } @Override public void removeSession(String sessionId) { SessionEntry se = this.sessionIdToEntry.remove(sessionId); logger.debug("removeSession({}) => {}", sessionId, se); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.data.ISessionDatasource#start() */ @Override public void start() { // NOP } /* * (non-Javadoc) * * @see org.jdiameter.common.api.data.ISessionDatasource#stop() */ @Override public void stop() { // NOP } /* * (non-Javadoc) * * @see org.jdiameter.common.api.data.ISessionDatasource#isClustered() */ @Override public boolean isClustered() { return false; } @Override public String toString() { return "LocalDataSource [sessionIdToEntry=" + sessionIdToEntry + "]"; } //simple class to reduce collections overhead. private class SessionEntry { BaseSession session; NetworkReqListener listener; @Override public String toString() { return "SessionEntry [session=" + session + ", listener=" + listener + "]"; } } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.data.ISessionDatasource#getDataFactory(java. * lang.Class) */ @Override public IAppSessionDataFactory getDataFactory(Class x) { return this.appSessionDataFactories.get(x); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/statistic/StatisticImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.statistic; import java.util.concurrent.ConcurrentLinkedQueue; import org.jdiameter.api.StatisticRecord; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.jdiameter.common.api.statistic.IStatisticRecord.Counters; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class StatisticImpl implements IStatistic { protected boolean enable = true; protected ConcurrentLinkedQueue records = new ConcurrentLinkedQueue(); protected String name; protected String description; protected IStatistic.Groups group; @Override public String getName() { return name; } @Override public String getDescription() { return description; } StatisticImpl(String name) { this.name = name; } StatisticImpl(String name, IStatistic.Groups group) { this(group.name() + "." + name); this.group = group; this.description = group.getDescription(); } // public StatisticImpl(String name, String desctiprion, IStatisticRecord... rec) { // this.name = name; // this.description = desctiprion; // for (IStatisticRecord r : rec) { // records.add((IStatisticRecord) r); // } // } StatisticImpl(String name, IStatistic.Groups group, String desctiprion, IStatisticRecord... rec) { this(name, group); this.description = desctiprion; for (IStatisticRecord r : rec) { records.add(r); } } @Override public void appendCounter(IStatisticRecord... rec) { for (IStatisticRecord r : rec) { r.enable(this.enable); records.add(r); } } @Override public IStatisticRecord getRecordByName(String name) { for (StatisticRecord r : records) { if (r.getName().equals(name)) { return (IStatisticRecord) r; } } return null; } @Override public IStatisticRecord getRecordByName(Counters name) { for (StatisticRecord r : records) { if (r.getName().equals(name.toString())) { return (IStatisticRecord) r; } } return null; } @Override public void enable(boolean e) { for (StatisticRecord r : records) { r.enable(e); } enable = e; } @Override public boolean isEnabled() { return enable; } @Override public void reset() { for (StatisticRecord r : records) { r.reset(); } } @Override public StatisticRecord[] getRecords() { return records.toArray(new StatisticRecord[0]); } @Override public String toString() { return "Statistic{" + " records=" + records + " }"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((group == null) ? 0 : group.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } StatisticImpl other = (StatisticImpl) obj; if (group != other.group) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/statistic/StatisticManagerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.statistic; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import org.jdiameter.api.Configuration; import org.jdiameter.client.impl.helpers.Parameters; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class StatisticManagerImpl implements IStatisticManager { //TODO: remove CopyOnWrite.... private List allStatistic = new CopyOnWriteArrayList(); private List allPSStatisticRecord = new CopyOnWriteArrayList(); private List frozenAllStatistic = Collections.unmodifiableList(allStatistic); private List frozenAllPSStatisticRecord = Collections.unmodifiableList(allPSStatisticRecord); private boolean enabled; private long pause, delay; private Set activeRecords; //list of stats enabled on start public StatisticManagerImpl(Configuration config) { long pause = (Long) Parameters.StatisticsLoggerPause.defValue(); long delay = (Long) Parameters.StatisticsLoggerDelay.defValue(); boolean enabled = (Boolean) Parameters.StatisticsEnabled.defValue(); String activeRecords = (String) Parameters.Statistics.defValue(); Configuration[] loggerParams = config.getChildren(Parameters.Statistics.ordinal()); if (loggerParams != null && loggerParams.length > 0) { pause = loggerParams[0].getLongValue(Parameters.StatisticsLoggerPause.ordinal(), pause); delay = loggerParams[0].getLongValue(Parameters.StatisticsLoggerDelay.ordinal(), delay); enabled = loggerParams[0].getBooleanValue(Parameters.StatisticsEnabled.ordinal(), enabled); activeRecords = loggerParams[0].getStringValue(Parameters.StatisticsActiveList.ordinal(), activeRecords); } this.pause = pause; this.delay = delay; this.enabled = enabled; Set enabledSet = new HashSet(); if (activeRecords != null && activeRecords.length() > 0) { for (String s : activeRecords.split(",")) { enabledSet.add(s); } } this.activeRecords = Collections.unmodifiableSet(enabledSet); } @Override public IStatisticRecord newCounterRecord(IStatisticRecord.Counters recordDescription) { StatisticRecordImpl statisticRecord = new StatisticRecordImpl(recordDescription.name(), recordDescription.getDescription()); statisticRecord.enable(this.isEnabled(recordDescription.name())); return statisticRecord; } @Override public IStatisticRecord newCounterRecord(IStatisticRecord.Counters recordDescription, IStatisticRecord.ValueHolder counters) { StatisticRecordImpl statisticRecord = new StatisticRecordImpl(recordDescription.name(), recordDescription.getDescription(), counters); statisticRecord.enable(this.isEnabled(recordDescription.name())); return statisticRecord; } @Override public IStatisticRecord newCounterRecord(IStatisticRecord.Counters recordDescription, IStatisticRecord.ValueHolder counter, IStatisticRecord... rec) { StatisticRecordImpl statisticRecord = new StatisticRecordImpl(recordDescription.name(), recordDescription.getDescription(), counter, rec); statisticRecord.enable(this.isEnabled(recordDescription.name())); return statisticRecord; } @Override public IStatisticRecord newCounterRecord(String name, String description) { StatisticRecordImpl statisticRecord = new StatisticRecordImpl(name, description); statisticRecord.enable(this.isEnabled(name)); return statisticRecord; } @Override public IStatisticRecord newCounterRecord(String name, String description, IStatisticRecord.ValueHolder counters) { StatisticRecordImpl statisticRecord = new StatisticRecordImpl(name, description, counters); statisticRecord.enable(this.isEnabled(name)); return statisticRecord; } @Override public IStatisticRecord newPerSecondCounterRecord(String name, IStatisticRecord.Counters recordDescription, IStatisticRecord child) { IStatisticRecord prevValue = new StatisticRecordImpl(name, recordDescription.getDescription()); IStatisticRecord psStatistic = new StatisticRecordImpl(recordDescription.name() + "." + name, recordDescription.getDescription(), child, prevValue); if (allPSStatisticRecord.contains(psStatistic)) { throw new IllegalArgumentException("Statistic already defined: " + psStatistic); } allPSStatisticRecord.add(psStatistic); return psStatistic; } @Override public IStatistic newStatistic(String name, IStatistic.Groups group, IStatisticRecord... rec) { IStatistic statistic = new StatisticImpl(name, group, group.getDescription(), rec); statistic.enable(this.isEnabled(statistic.getName())); if (allStatistic.contains(statistic)) { throw new IllegalArgumentException("Statistic already defined: " + statistic); } allStatistic.add(statistic); return statistic; } // public IStatistic newStatistic(String name, String description, IStatisticRecord... rec) { // //FIXME: remove this? // IStatistic statistic = new StatisticImpl(name, description, rec); // statistic.enable(this.isEnabled(statistic.getName())); // if (allStatistic.contains(statistic)) { // throw new IllegalArgumentException("Statistic already defined: "+statistic); // } // allStatistic.add(statistic); // return statistic; // } // // public void removePerSecondCounterRecord(String name, IStatisticRecord.Counters recordDescription) { // IStatisticRecord record = new StatisticRecordImpl(recordDescription+"."+name, recordDescription.getDescription()); // this.allPSStatisticRecord.remove(record); // } // // public void removeStatistic(String name) { // IStatistic statistic = new StatisticImpl(name); // this.allStatistic.remove(statistic); // } // // public void removeStatistic(String name, IStatistic.Groups group) { // IStatistic statistic = new StatisticImpl(name, group); // this.allStatistic.remove(statistic); // } @Override public void removePerSecondCounterRecord(IStatisticRecord rec) { this.allPSStatisticRecord.remove(rec); } @Override public void removeStatistic(IStatistic stat) { this.allStatistic.remove(stat); } private boolean isEnabled(String name) { if (this.activeRecords.contains(name)) { return true; } //else lets check prefixes. while (name.indexOf(".") > 0) { name = name.substring(0, name.lastIndexOf(".")); if (this.activeRecords.contains(name)) { return true; } } return this.activeRecords.contains(name); } @Override public boolean isOn() { return enabled; } @Override public long getPause() { return pause; } @Override public long getDelay() { return delay; } @Override public Set getEnabled() { return activeRecords; } @Override public List getPSStatisticRecord() { return this.frozenAllPSStatisticRecord; } @Override public List getStatistic() { return this.frozenAllStatistic; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/statistic/StatisticProcessorImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.statistic; import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.StatisticTimer; import java.util.HashMap; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.jdiameter.api.Configuration; import org.jdiameter.api.StatisticRecord; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticProcessor; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Statistics Processor * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class StatisticProcessorImpl implements IStatisticProcessor { private static final Logger logger = LoggerFactory.getLogger(StatisticProcessorImpl.class); private ScheduledExecutorService executorService; private IConcurrentFactory concurrentFactory; private IStatisticManager statisticFactory; // statics for logger names private static final String STATS_ROOT_LOGGER_NAME = "jdiameter.statistic"; private static final String STATS_LOGGER_PREFIX = "jdiameter.statistic."; // future for actions to update per second stats private Future processorFuture; // future for logger runnable private Future logFuture; // map of loggers, so we dont have to fetch from slf all the time private HashMap loggers = new HashMap(); public StatisticProcessorImpl(Configuration config, IConcurrentFactory concurrentFactory, final IStatisticManager statisticFactory) { this.statisticFactory = statisticFactory; this.concurrentFactory = concurrentFactory; } @Override public void start() { if (!this.statisticFactory.isOn()) { return; } this.executorService = concurrentFactory.getScheduledExecutorService(StatisticTimer.name()); // start processor this.processorFuture = this.executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { try { for (IStatisticRecord r : ((StatisticManagerImpl) statisticFactory).getPSStatisticRecord()) { StatisticRecord[] recs = r.getChilds(); // magic of PS records, there are two children created... IStatisticRecord realRecord = (IStatisticRecord) recs[0]; IStatisticRecord prevRecord = (IStatisticRecord) recs[1]; r.setLongValue(realRecord.getValueAsLong() - prevRecord.getValueAsLong()); prevRecord.setLongValue(realRecord.getValueAsLong()); } } catch (Exception e) { logger.warn("Can not start persecond statistic", e); } } }, 0, 1, TimeUnit.SECONDS); // start logging actions this.logFuture = this.executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { boolean oneLine = false; for (IStatistic statistic : statisticFactory.getStatistic()) { if (statistic.isEnabled()) { for (StatisticRecord record : statistic.getRecords()) { oneLine = true; String loggerKey = statistic.getName() + "." + record.getName(); Logger logger = null; if ((logger = loggers.get(loggerKey)) == null) { logger = LoggerFactory.getLogger(STATS_LOGGER_PREFIX + loggerKey); loggers.put(loggerKey, logger); } if (logger.isTraceEnabled()) { logger.trace(record.toString()); } } } } if (oneLine) { Logger logger = null; if ((logger = loggers.get(STATS_ROOT_LOGGER_NAME)) == null) { logger = LoggerFactory.getLogger(STATS_ROOT_LOGGER_NAME); loggers.put(STATS_ROOT_LOGGER_NAME, logger); } if (logger.isTraceEnabled()) { logger.trace( "=============================================== Marker ==============================================="); } } } }, statisticFactory.getPause(), statisticFactory.getDelay(), TimeUnit.MILLISECONDS); } @Override public void stop() { if (!this.statisticFactory.isOn()) { return; } if (this.processorFuture != null) { this.processorFuture.cancel(false); this.processorFuture = null; } if (this.logFuture != null) { this.logFuture.cancel(false); this.logFuture = null; } this.concurrentFactory.shutdownNow(executorService); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/statistic/StatisticRecordImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.statistic; import java.util.Arrays; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicLong; import org.jdiameter.api.StatisticRecord; import org.jdiameter.common.api.statistic.IStatisticRecord; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class StatisticRecordImpl implements IStatisticRecord { protected boolean enable = true; protected String name; protected String description; protected Counters counter; protected AtomicLong value; protected ConcurrentLinkedQueue childs = new ConcurrentLinkedQueue(); protected ValueHolder valueHolder; StatisticRecordImpl(String name) { this.name = name; this.value = new AtomicLong(0); } StatisticRecordImpl(String name, String description) { this(name); this.description = description; } StatisticRecordImpl(String name, Counters counter) { this(counter.name() + "." + name); this.counter = counter; this.description = counter.getDescription(); } StatisticRecordImpl(String name, String description, IStatisticRecord... childs) { this(name, description); this.childs.addAll(Arrays.asList(childs)); } StatisticRecordImpl(String name, String description, ValueHolder valueHolder) { this(name, description); this.valueHolder = valueHolder; } StatisticRecordImpl(String name, String description, ValueHolder valueHolder, IStatisticRecord... childs) { this(name, description, valueHolder); this.childs.addAll(Arrays.asList(childs)); } StatisticRecordImpl(String name, String description, long value) { this(name, description); this.value = new AtomicLong(value); } @Override public String getName() { return name; } @Override public String getDescription() { return description; } @Override public int getValueAsInt() { return valueHolder != null ? ((IntegerValueHolder) valueHolder).getValueAsInt() : (int) value.get(); } @Override public double getValueAsDouble() { return valueHolder != null ? ((DoubleValueHolder) valueHolder).getValueAsDouble() : Double.longBitsToDouble(value.get()); } @Override public long getValueAsLong() { return valueHolder != null ? ((LongValueHolder) valueHolder).getValueAsLong() : value.get(); } @Override public void inc() { if (enable) { this.value.incrementAndGet(); } } @Override public void inc(long delta) { if (enable) { this.value.addAndGet(delta); } } @Override public void setDoubleValue(double value) { if (enable) { this.value.set(Double.doubleToLongBits(value)); } } @Override public void setLongValue(long value) { if (enable) { this.value.set(value); } } @Override public void dec() { if (enable) { value.decrementAndGet(); } } @Override public StatisticRecord[] getChilds() { return childs.toArray(new StatisticRecord[0]); } @Override public void reset() { value.set(0); } @Override public void enable(boolean e) { for (StatisticRecord r : childs) { r.enable(e); } enable = e; } @Override public boolean isEnabled() { return this.enable; } @Override public String toString() { return String.valueOf(valueHolder != null ? valueHolder.getValueAsString() : value.get()); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((counter == null) ? 0 : counter.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } StatisticRecordImpl other = (StatisticRecordImpl) obj; if (counter != other.counter) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/timer/LocalTimerFacilityImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.timer; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.Serializable; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.commons.pool.BasePoolableObjectFactory; import org.apache.commons.pool.impl.GenericObjectPool; import org.jdiameter.api.BaseSession; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.impl.BaseSessionImpl; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.api.timer.ITimerFacility; import org.jdiameter.common.impl.app.AppSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Local implementation of timer facility for {@link ITimerFacility} * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class LocalTimerFacilityImpl implements ITimerFacility { private static final Logger logger = LoggerFactory.getLogger(LocalTimerFacilityImpl.class); private ScheduledThreadPoolExecutor executor; private ISessionDatasource sessionDataSource; // TimerTaskHandle pooling to minimize impact on Eden space and avoid too // much GC, consequently not loosing time during GC private final GenericObjectPool pool = new GenericObjectPool(new TimerTaskHandleFactory(), 100000, GenericObjectPool.WHEN_EXHAUSTED_GROW, 10, 20000); public LocalTimerFacilityImpl(IContainer container) { super(); this.executor = (ScheduledThreadPoolExecutor) container.getConcurrentFactory() .getScheduledExecutorService(IConcurrentFactory.ScheduledExecServices.ApplicationSession.name()); this.sessionDataSource = container.getAssemblerFacility().getComponentInstance(ISessionDatasource.class); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.timer.ITimerFacility#cancel(java.io.Serializable) */ @Override public void cancel(Serializable f) { if (f != null && f instanceof TimerTaskHandle) { TimerTaskHandle timerTaskHandle = (TimerTaskHandle) f; if (timerTaskHandle.future != null) { logger.debug("Cancelling timer with id [{}] and delay [{}]", timerTaskHandle.id, timerTaskHandle.future.getDelay(TimeUnit.MILLISECONDS)); if (executor.remove((Runnable) timerTaskHandle.future)) { timerTaskHandle.future.cancel(false); returnTimerTaskHandle(timerTaskHandle); } } } } /* * (non-Javadoc) * * @see org.jdiameter.common.api.timer.ITimerFacility#schedule(java.lang.String, java.lang.String, long) */ @Override public Serializable schedule(String sessionId, String timerName, long milliseconds) throws IllegalArgumentException { String id = sessionId + "/" + timerName; logger.debug("Scheduling timer with id [{}]", id); TimerTaskHandle ir = borrowTimerTaskHandle(); ir.id = id; ir.sessionId = sessionId; ir.timerName = timerName; ir.future = this.executor.schedule(ir, milliseconds, TimeUnit.MILLISECONDS); return ir; } protected void returnTimerTaskHandle(TimerTaskHandle timerTaskHandle) { try { pool.returnObject(timerTaskHandle); } catch (Exception e) { logger.warn(e.getMessage()); } } protected TimerTaskHandle borrowTimerTaskHandle() { try { TimerTaskHandle timerTaskHandle = (TimerTaskHandle) pool.borrowObject(); return timerTaskHandle; } catch (Exception e) { logger.error("", e); } return null; } class TimerTaskHandleFactory extends BasePoolableObjectFactory { @Override public Object makeObject() throws Exception { return new TimerTaskHandle(); } @Override public void passivateObject(Object obj) throws Exception { TimerTaskHandle timerTaskHandle = (TimerTaskHandle) obj; timerTaskHandle.id = null; timerTaskHandle.sessionId = null; timerTaskHandle.timerName = null; timerTaskHandle.future = null; } } private final class TimerTaskHandle implements Runnable, Externalizable { // its not really serializable; private String sessionId; private String timerName; private String id; //for debug, easier to check what's going on and what that timer does. private transient ScheduledFuture future; @Override public void run() { try { BaseSession bSession = sessionDataSource.getSession(sessionId); if (bSession == null) { // FIXME: error ? logger.error("Base Session is null for sessionId: {}", sessionId); return; } else { try { if (!bSession.isAppSession()) { BaseSessionImpl impl = (BaseSessionImpl) bSession; impl.onTimer(timerName); } else { AppSessionImpl impl = (AppSessionImpl) bSession; impl.onTimer(timerName); } } catch (Exception e) { logger.error("Caught exception from session object!", e); } } } catch (Exception e) { logger.error("Failure executing timer task witb id: " + id, e); } finally { returnTimerTaskHandle(this); } } /* * (non-Javadoc) * * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) */ @Override public void writeExternal(ObjectOutput out) throws IOException { throw new IOException("Failed to serialize local timer!"); } /* * (non-Javadoc) * * @see java.io.Externalizable#readExternal(java.io.ObjectInput) */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { throw new IOException("Failed to deserialize local timer!"); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/validation/AvpRepresentationImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.validation; import java.util.ArrayList; import java.util.List; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.validation.AvpNotAllowedException; import org.jdiameter.api.validation.AvpRepresentation; /** * Implementation of {@link AvpRepresentation} interface. * * @author Bartosz Baranowski * @author Alexandre Mendonca * @since 1.5.4.0-build404 */ @SuppressWarnings("all") //3rd party lib public class AvpRepresentationImpl implements AvpRepresentation { protected String description; protected boolean mayEncrypt; protected boolean _protected; protected boolean _mandatory; protected String ruleMandatory; protected String ruleProtected; protected String ruleVendorBit; protected String originalType; protected String type; // String, in case user defines his own type // Usually this will be -1, as only SessionId has fixed position private int positionIndex = _FIX_POSITION_INDEX; protected int code = -1; protected long vendor = 0; protected boolean allowed = true; protected String multiplicityIndicator = "0"; protected String name = "Some-AVP"; protected boolean grouped = false; protected List children = new ArrayList(); protected boolean weak = false; public AvpRepresentationImpl(AvpRepresentationImpl clone) { this(-1, clone.code, clone.getVendorId(), clone.getMultiplicityIndicator(), clone.getName()); this.allowed = clone.allowed; this.code = clone.code; this.grouped = clone.grouped; this.multiplicityIndicator = clone.multiplicityIndicator; this.name = clone.name; this.positionIndex = clone.positionIndex; this.vendor = clone.vendor; this.weak = clone.weak; this._mandatory = clone._mandatory; this._protected = clone._protected; this.description = clone.description; this.mayEncrypt = clone.mayEncrypt; this.ruleMandatory = clone.ruleMandatory; this.ruleProtected = clone.ruleProtected; this.ruleVendorBit = clone.ruleVendorBit; this.originalType = clone.originalType; this.type = clone.type; if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED)) { this.allowed = false; } } public AvpRepresentationImpl() { super(); this.weak = true; } /** * Constructor used to represent weak children. - weak means its only defined by name in some other AVP. After * configuration parse procedure is complete weak children are resolved. Weak children should not be stored in Set * or any other has structure, its due to nature of hashing, which is done on vendor and code, which for weak * children is always different than fully defined AVP representation.
      * This constructor should be generally * used by extending classes, as well as no argument constructor. * * @param name * @param vendor */ public AvpRepresentationImpl(String name, long vendor) { super(); this.name = name; this.vendor = vendor; this.weak = true; } /** * This constructor is used my validator to lookup correct representation. Its hash and equals methods will match to * fully populated avp representation in any data structure * * @param code * @param vendor */ public AvpRepresentationImpl(int code, long vendor) { super(); this.code = code; this.vendor = vendor; if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED)) { this.allowed = false; } } public AvpRepresentationImpl(int positionIndex, int code, long vendor, String multiplicityIndicator, String name) { super(); this.positionIndex = positionIndex; this.code = code; this.vendor = vendor; this.multiplicityIndicator = multiplicityIndicator; this.name = name; if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED)) { this.allowed = false; } } public AvpRepresentationImpl(int code, long vendor, String name) { super(); this.positionIndex = -1; this.code = code; this.vendor = vendor; this.multiplicityIndicator = _MP_ZERO_OR_MORE; this.name = name; if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED)) { this.allowed = false; } } public AvpRepresentationImpl(String name, String description, int code, boolean mayEncrypt, String ruleMandatory, String ruleProtected, String ruleVendorBit, long vendorId, String originalType, String type) { // zero and more, since its definition. this(-1, code, vendorId, _MP_ZERO_OR_MORE, name); this.description = description; this.mayEncrypt = mayEncrypt; this.ruleMandatory = ruleMandatory; this.ruleProtected = ruleProtected; this.ruleVendorBit = ruleVendorBit; if (this.ruleMandatory == null || this.ruleMandatory.equals("")) { this.ruleMandatory = _DEFAULT_MANDATORY; } if (this.ruleProtected == null || this.ruleProtected.equals("")) { this.ruleProtected = _DEFAULT_PROTECTED; } if (this.ruleVendorBit == null || this.ruleVendorBit.equals("")) { this.ruleVendorBit = _DEFAULT_VENDOR; } this.originalType = originalType; this.type = type; this._mandatory = this.ruleMandatory.equals("must"); this._protected = this.ruleProtected.equals("must"); if (type.equals(Type.Grouped.toString())) { this.setGrouped(true); } if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED)) { this.allowed = false; } } @Override public boolean isPositionFixed() { return this.positionIndex == _FIX_POSITION_INDEX; } public void markFixPosition(int index) { this.positionIndex = index; } @Override public boolean isCountValidForMultiplicity(AvpSet destination, int numberToAdd) { AvpSet innerSet = destination.getAvps(getCode(), getVendorId()); int count = numberToAdd; if (innerSet != null) { count += innerSet.size(); } return this.isCountValidForMultiplicity(count); } @Override public boolean isCountValidForMultiplicity(int avpCount) { // This covers not_allowed if (!allowed) { if (avpCount == 0) { return true; } } else { if (this.multiplicityIndicator.equals(_MP_ZERO_OR_MORE)) { if (avpCount >= 0) { return true; } } else if (this.multiplicityIndicator.equals(_MP_ZERO_OR_ONE)) { if ((avpCount == 0) || (avpCount == 1)) { return true; } } else if (this.multiplicityIndicator.equals(_MP_ONE)) { if (avpCount == 1) { return true; } } else if (this.multiplicityIndicator.equals(_MP_ONE_AND_MORE)) { if (avpCount >= 1) { return true; } } } // if we did not return, we are screwed. return false; } public static int get_FIX_POSITION_INDEX() { return _FIX_POSITION_INDEX; } @Override public int getPositionIndex() { return positionIndex; } @Override public int getCode() { return code; } @Override public long getVendorId() { return vendor; } @Override public boolean isAllowed() { return allowed; } @Override public boolean isAllowed(int avpCode, long vendorId) { if (this.isGrouped()) { // make better get ? for (AvpRepresentation rep : this.children) { if (rep.getCode() == avpCode && rep.getVendorId() == vendorId) { return rep.isAllowed(); } else { continue; } } return true; } else { return false; } } @Override public boolean isAllowed(int avpCode) { return this.isAllowed(avpCode, 0L); } @Override public String getMultiplicityIndicator() { return multiplicityIndicator; } @Override public String getName() { return name; } @Override public boolean isGrouped() { return grouped; } public void setGrouped(boolean grouped) { this.grouped = grouped; } @Override public List getChildren() { return children; } public void setChildren(List children) { this.children = children; } public void setCode(int code) { this.code = code; } public void setVendorId(long vendor) { this.vendor = vendor; } public void setMultiplicityIndicator(String multiplicityIndicator) { this.multiplicityIndicator = multiplicityIndicator; if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED)) { this.allowed = false; } } public void setName(String name) { this.name = name; } @Override public boolean isWeak() { return weak; } public void markWeak(boolean isWeak) { this.weak = isWeak; } @Override public String getDescription() { return description; } @Override public boolean isMayEncrypt() { return mayEncrypt; } @Override public String getRuleMandatory() { return ruleMandatory; } @Override public int getRuleMandatoryAsInt() { return Rule.valueOf(ruleMandatory).ordinal(); } @Override public String getRuleProtected() { return ruleProtected; } @Override public int getRuleProtectedAsInt() { return Rule.valueOf(ruleProtected).ordinal(); } @Override public String getRuleVendorBit() { return ruleVendorBit; } @Override public int getRuleVendorBitAsInt() { return Rule.valueOf(ruleVendorBit).ordinal(); } @Override public String getOriginalType() { return originalType; } @Override public String getType() { return type; } @Override public boolean isProtected() { return _protected; } @Override public boolean isMandatory() { return _mandatory; } @Override public void validate(Avp avp) throws AvpNotAllowedException { if (isGrouped()) { try { AvpSet avpAsGrouped = avp.getGrouped(); validate(avpAsGrouped); } catch (AvpDataException e) { throw new AvpNotAllowedException("Failed to parse AVP to grouped!", e, code, vendor); } } else { // dont care } } @Override public void validate(AvpSet avpSet) throws AvpNotAllowedException { //this is used in RAs, cause ... AvpSet is asexual AVP, no code, no vendor // let it rip for (AvpRepresentation childrenVAvp : getChildren()) { AvpSet childSset = avpSet.getAvps(childrenVAvp.getCode(), childrenVAvp.getVendorId()); int count = childSset.size(); if (!childrenVAvp.isCountValidForMultiplicity(count)) { throw new AvpNotAllowedException( "AVP: " + childrenVAvp + " has wrong count, in grouped parent avp - " + (count) + ", allowed: " + childrenVAvp.getMultiplicityIndicator(), getCode(), getVendorId()); } if (childrenVAvp.isGrouped()) { for (int index = 0; index < childSset.size(); index++) { Avp presumablyGrouped = childSset.getAvpByIndex(index); childrenVAvp.validate(presumablyGrouped); } } // else we are good ? } } @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("name: ").append(this.getName()).append(", code: ").append(this.getCode()).append(", vendor: ") .append(this.getVendorId()).append(", weak: ") .append(this.isWeak()).append(", grouped: ").append(this.isGrouped()).append(", type: ").append(this.getType()) .append(", multiplicity: ") .append(this.getMultiplicityIndicator()); if (this.isGrouped()) { for (AvpRepresentation child : this.getChildren()) { String childStr = child.toString().replace("\n", "\n---"); sb.append("\n---" + childStr); } } return sb.toString(); } @Override public int hashCode() { // code+vendor is enough by AVP def final int prime = 31; int result = 1; result = prime * result + code; result = prime * result + (int) (vendor ^ (vendor >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } // code+vendor is enough by AVP def AvpRepresentationImpl other = (AvpRepresentationImpl) obj; if (code != other.code) { return false; } if (vendor != other.vendor) { return false; } return true; } @Override public Object clone() throws CloneNotSupportedException { AvpRepresentationImpl clone = new AvpRepresentationImpl(); clone.allowed = this.allowed; clone.code = this.code; clone.grouped = this.grouped; clone.multiplicityIndicator = this.multiplicityIndicator; clone.name = this.name; clone.positionIndex = this.positionIndex; clone.vendor = this.vendor; clone.weak = this.weak; clone._mandatory = this._mandatory; clone._protected = this._protected; clone.description = this.description; clone.mayEncrypt = this.mayEncrypt; clone.ruleMandatory = this.ruleMandatory; clone.ruleProtected = this.ruleProtected; clone.ruleVendorBit = this.ruleVendorBit; clone.originalType = this.originalType; clone.type = this.type; List cloneChildren = new ArrayList(); clone.children = cloneChildren; for (AvpRepresentation c : this.children) { cloneChildren.add((AvpRepresentation) c.clone()); } return clone; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/validation/DictionaryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.validation; import org.jdiameter.api.Message; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.api.validation.*; import org.jdiameter.client.impl.DictionarySingleton; import org.jdiameter.client.impl.VersionProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.*; import java.util.*; /** * Implementation of {@link Dictionary} interface. * * @author Bartosz Baranowski * @author Alexandre Mendonca * @since 1.5.4.0-build404 */ @SuppressWarnings("all") //3rd party lib public class DictionaryImpl implements Dictionary { private static transient Logger logger = LoggerFactory.getLogger(DictionaryImpl.class); public static Dictionary INSTANCE = getInstance("dictionary.xml"); private static final String UNDEFINED_AVP_TYPE = "UNDEFINED"; private static final String AVP_DEFAULT_INDEX = "-1"; private static final String AVP_DEFAULT_MULTIPLICITY = AvpRepresentation._MP_ZERO_OR_MORE; public static final String _AVP_ATTRIBUTE_NAME = "name"; public static final String _AVP_ATTRIBUTE_CODE = "code"; public static final String _AVP_ATTRIBUTE_VENDOR = "vendor"; public static final String _AVP_ATTRIBUTE_MULTIPLICITY = "multiplicity"; public static final String _AVP_ATTRIBUTE_INDEX = "index"; private Map avpMap = new HashMap(); private Map avpByNameMap = new HashMap(); private Map vendorMap = new HashMap(); private Map commandMap = new HashMap(); private Map typedefMap = new HashMap(); private boolean configured = false; private DictionaryImpl(InputStream is) { init(is); } public static Dictionary getInstance(InputStream is) { if (is == null) { if (INSTANCE != null) { return INSTANCE; } // Maintaining 1.7.0 behaviour String confFile = "dictionary.xml"; is = getInputStream(confFile); } if (INSTANCE != null) { ((DictionaryImpl) INSTANCE).init(is); } else { INSTANCE = new DictionaryImpl(is); } return INSTANCE; } public static Dictionary getInstance(String confFile) { if (confFile == null) { if (INSTANCE != null) { return INSTANCE; } confFile = "dictionary.xml"; } InputStream is = getInputStream(confFile); return getInstance((InputStream) is); } private static InputStream getInputStream(String confFile) { InputStream is = null; try { is = DictionarySingleton.class.getResourceAsStream(confFile); if (is == null) { logger.debug( "Dictionary configuration file: {}, not found in class classloader. Trying thread context class loader.", confFile); is = Thread.currentThread().getContextClassLoader().getResourceAsStream(confFile); } if (is == null) { logger.debug( "Dictionary configuration file: {}, not found in thread context class loader. Trying using 'config/' prefix.", confFile); is = Thread.currentThread().getContextClassLoader().getResourceAsStream("config/" + confFile); } if (is == null) { logger.debug( "Fictionary configuration file: {}, not found in thread context class loader. Trying regular file.", confFile); File fDict = new File(confFile); if (fDict.exists()) { is = new FileInputStream(fDict); } else { logger.debug( "Dictionary configuration file: {}, not found from regular file. Trying using 'config/' prefix.", confFile); fDict = new File("config/" + confFile); if (fDict.exists()) { is = new FileInputStream(fDict); } } } } catch (FileNotFoundException fnfe) { logger.warn("Could not load configuration file: {}, from any known location.", confFile); } return is; } private void init(InputStream is) { try { if (is != null) { this.configure(is); } else { this.setEnabled(false); logger.warn( "Failed to initialize and configure Diameter Dictionary since configuration file was not found. Validator is disabled."); } } finally { if (is != null) { try { is.close(); } catch (IOException e) { logger.error("", e); } } } } // Parser functions --------------------------------------------------------- /* * (non-Javadoc) * * @see org.jdiameter.api.validation.Dictionary#configure(java.io.InputStream) */ @Override public void configure(InputStream is) { if (is == null) { logger.error("No input stream to configure dictionary from?"); return; } try { long startTime = System.currentTimeMillis(); this.avpByNameMap = new TreeMap(new Comparator() { @Override public int compare(String o1, String o2) { return (o1 == null) ? 1 : (o2 == null) ? -1 : o1.compareTo(o2); } }); this.vendorMap = new HashMap(); this.typedefMap = new HashMap(); this.avpMap = new HashMap(); this.commandMap = new HashMap(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setValidating(false); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(is); doc.getDocumentElement().normalize(); this.parseVendors(doc); this.parseTypeDefs(doc); this.parseAvps(doc); this.parseCommands(doc); this.configured = true; long endTime = System.currentTimeMillis(); if (logger.isInfoEnabled()) { logger.info("{} Diameter Dictionary loaded in {}ms -- Vendors[{}] Commands[{}] Types[{}] AVPs[{}]", new Object[]{VersionProperties.instance.getProperty("vendor"), (endTime - startTime), vendorMap.size(), commandMap.size(), typedefMap.size(), avpMap.size()}); } if (logger.isInfoEnabled()) { StringBuffer sb = new StringBuffer(); int c = 0; for (AvpRepresentation key : this.avpMap.keySet()) { if (this.avpMap.get(key).isWeak()) { c++; sb.append("---------------------------------\n").append("Found incomplete AVP definition:\n") .append(this.avpMap.get(key)).append("\n"); } } if (c > 0) { sb.append("------- TOTAL INCOMPLETE AVPS COUNT: ").append(c).append(" -------"); logger.info(sb.toString()); } } } catch (Exception e) { this.enabled = false; this.configured = false; logger.error("Failed to parse validator configuration. Validator disabled.", e); } finally { // close? try { is.close(); } catch (IOException e) { logger.debug("Failed to close InputStream for Dictionary XML.", e); } } } /** * Parses the attributes from a Dictionary XML Document * * @param doc the DOM object representing the XML Document with the Dictionary definitions */ protected void parseVendors(Document doc) { // Parse vendors, we will need those. // Format: NodeList vendorNodes = doc.getElementsByTagName("vendor"); for (int v = 0; v < vendorNodes.getLength(); v++) { Node vendorNode = vendorNodes.item(v); if (vendorNode.getNodeType() == Node.ELEMENT_NODE) { Element vendorElement = (Element) vendorNode; // Get the Code (number) and ID (string) String vendorCode = vendorElement.getAttribute("code"); String vendorId = vendorElement.getAttribute("vendor-id"); vendorMap.put(vendorId, vendorCode); } } } /** * Parses the attributes from a Dictionary XML Document * * @param doc the DOM object representing the XML Document with the Dictionary definitions */ protected void parseTypeDefs(Document doc) { // Parse type definitions. Handy to match against defined AVP types // and to fill AVPs with generic function. // Format: // NodeList typedefNodes = doc.getElementsByTagName("typedefn"); for (int td = 0; td < typedefNodes.getLength(); td++) { Node typedefNode = typedefNodes.item(td); if (typedefNode.getNodeType() == Node.ELEMENT_NODE) { Element typedefElement = (Element) typedefNode; String typeName = typedefElement.getAttribute("type-name"); String typeParent = typedefElement.getAttribute("type-parent"); // UTF8String and Time are special situations, we don't want to convert these. if (typeParent == null || typeParent.equals("") || typeName.equals("UTF8String") || typeName.equals("Time")) { typeParent = typeName; } typedefMap.put(typeName, typeParent); } } } public void addAvpDef(String avpName, String avpDesc, long vendorId, int avpCode, boolean avpMayEncrypt, String avpMandatory, String avpProtected, String avpVendorBit, String originalType, String avpType, List groupedAvpChilds) { try { AvpRepresentationImpl avp = null; avp = new AvpRepresentationImpl(avpName, avpDesc, Integer.valueOf(avpCode), avpMayEncrypt, avpMandatory, avpProtected, avpVendorBit, vendorId, originalType, avpType); if (avp.isGrouped()) { avp.setChildren(groupedAvpChilds); // we are not strong enough, children are referenced ONLY by name, so we are // weak until all children can be resolved to strong representation avp.markWeak(true); } resolveWeakLinks(avp); AvpRepresentation existingAvp = null; if ((existingAvp = avpMap.get(avp)) != null) { logger.warn("Duplicated AVP Definition for AVP Code: {}, Vendor-Id: {}. See TRACE logs for definitions.", avp.getCode(), avp.getVendorId()); logger.trace("Existing AVP:\r\n {}\r\n New AVP:\r\n {}", existingAvp, avp); } else { avpMap.put(avp, avp); } AvpRepresentation oldAvp = avpByNameMap.put(avp.getName(), avp); if (oldAvp != null && avp.weak) { logger.debug("[WARN] Overwrited definition of AVP with the same name: Old: {}, New: {}", new Object[]{oldAvp, avp}); } } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug(new StringBuffer("[ERROR] Failed adding AVP: Name[").append(avpName).append("] Description[") .append("N/A").append("] Code[").append(avpCode).append("] May-Encrypt[").append(avpMayEncrypt) .append("] Mandatory[").append(avpMandatory).append("] Protected [").append(avpProtected) .append("] Vendor-Bit [").append(avpVendorBit).append("] Vendor-Id [").append(vendorId) .append("] Constrained[").append("N/A").append("] OriginalType [").append(originalType) .append("] Type [").append(avpType).append("]").toString(), e); } } } /** * Parses the attributes from a Dictionary XML Document * * @param doc the DOM object representing the XML Document with the Dictionary definitions */ protected void parseAvps(Document doc) { // Format: // // NodeList avpDefnNodes = doc.getElementsByTagName("avpdefn"); for (int i = 0; i < avpDefnNodes.getLength(); i++) { Node avpNode = avpDefnNodes.item(i); Element avpDefnElement = (Element) avpNode; String avpName = avpDefnElement.getAttribute("name"); String avpCode = avpDefnElement.getAttribute("code"); String avpVendorId = avpDefnElement.getAttribute("vendor-id"); String avpMandatory = avpDefnElement.getAttribute("mandatory"); String avpProtected = avpDefnElement.getAttribute("protected").equals("") ? "may" : avpDefnElement.getAttribute("protected"); String avpMayEncrypt = avpDefnElement.getAttribute("may-encrypt"); String avpVendorBit = avpDefnElement.getAttribute("vendor-bit"); long vendorCode = getVendorCode(avpVendorId); // Let's figure out the type // It can be: // // OR // ... // OR // ... String avpOriginalType = UNDEFINED_AVP_TYPE; String avpType = avpOriginalType; List groupedAvpChilds = new ArrayList(); NodeList avpDefnChildNodes = avpNode.getChildNodes(); for (int j = 0; j < avpDefnChildNodes.getLength(); j++) { Node avpDefnChildNode = avpDefnChildNodes.item(j); if (avpDefnChildNode.getNodeType() == Node.ELEMENT_NODE) { Element avpDefnChildElement = (Element) avpDefnChildNode; if (avpDefnChildElement.getNodeName().equals("grouped")) { avpOriginalType = "Grouped"; avpType = avpOriginalType; // Let's fetch the childs // Format: NodeList groupedAvpMembers = avpDefnChildElement.getChildNodes(); for (int gChildIndex = 0; gChildIndex < groupedAvpMembers.getLength(); gChildIndex++) { Node groupedAvpChildNode = groupedAvpMembers.item(gChildIndex); if (groupedAvpChildNode.getNodeType() == Node.ELEMENT_NODE) { Element groupedAvpChildElement = (Element) groupedAvpChildNode; String childName = null; String childMultiplicity = AVP_DEFAULT_MULTIPLICITY; String childIndexIndicator = AVP_DEFAULT_INDEX; if (!groupedAvpChildElement.hasAttribute("name")) { if (logger.isDebugEnabled()) { logger.debug(new StringBuffer( "[ERROR] Grouped child does not have name, grouped avp: Name[").append(avpName) .append("] Description[") .append("").append("] Code[").append(avpCode).append("] May-Encrypt[") .append(avpMayEncrypt).append("] Mandatory[") .append(avpMandatory).append("] Protected [").append(avpProtected) .append("] Vendor-Bit [").append(avpVendorBit).append("] Vendor-Id [") .append(avpVendorId).append("] Constrained[").append("").append("] Type [") .append(avpType).append("]").toString()); } continue; } else { childName = groupedAvpChildElement.getAttribute("name"); } childMultiplicity = groupedAvpChildElement.hasAttribute("multiplicity") ? groupedAvpChildElement.getAttribute("multiplicity") : AvpRepresentation._MP_ZERO_OR_MORE; childIndexIndicator = groupedAvpChildElement.hasAttribute("index") ? groupedAvpChildElement.getAttribute("index") : "-1"; // have we parsed this child definition already? AvpRepresentation childRep = this.avpByNameMap.get(childName); AvpRepresentationImpl child = null; if (childRep != null) { try { child = (AvpRepresentationImpl) childRep.clone(); } catch (CloneNotSupportedException cnse) { // It should not happen, but anyway if (logger.isWarnEnabled()) { logger.warn("Unable to clone AVP " + childRep, cnse); } } } else { child = new AvpRepresentationImpl(childName, vendorCode); child.markWeak(true); } child.setMultiplicityIndicator(childMultiplicity); child.markFixPosition(Integer.valueOf(childIndexIndicator)); groupedAvpChilds.add(child); } } } else if (avpDefnChildElement.getNodeName().equals("type")) { avpOriginalType = avpDefnChildElement.getAttribute("type-name"); avpType = avpOriginalType; //FIXME: baranowb: why this is like that? This changes type of AVP to primitive ONE..? Checks against type dont make sense, ie to check for Address type... avpType = typedefMap.get(avpType); if (avpType == null) { logger.warn("Unknown AVP Type ({}) for AVP with code {} and vendor-id {} ", new Object[]{avpDefnChildElement.getAttribute("type-name"), avpCode, avpVendorId}); } } else { logger.warn("Unknown AVP Definition child element for AVP with code {} and vendor-id {} ", avpCode, avpVendorId); } } } addAvpDef(avpName, "N/A", vendorCode, Integer.valueOf(avpCode), avpMayEncrypt.equals("yes"), avpMandatory, avpProtected, avpVendorBit, avpOriginalType, avpType, groupedAvpChilds); } for (AvpRepresentation rep : avpMap.values()) { markWeaks((AvpRepresentationImpl) rep); } } private boolean markWeaks(AvpRepresentationImpl rep) { if (rep.isGrouped()) { boolean isWeak = false; for (AvpRepresentation repC : rep.getChildren()) { if (markWeaks((AvpRepresentationImpl) repC)) { isWeak = true; } } rep.markWeak(isWeak); } else { rep.markWeak(rep.getCode() == -1); } return rep.isWeak(); } /** * For a given AVP resolves the weak links (where AVP definition in grouped AVPs is not yet known, and only added by * Name) * * @param newAvp the AVP which was just defined */ private void resolveWeakLinks(AvpRepresentation newAvp) { for (AvpRepresentation avp : avpMap.values()) { if (avp.isGrouped()) { if (avp.getName().equals(newAvp.getName())) { continue; } List avpChilds = avp.getChildren(); for (int n = 0; n < avpChilds.size(); n++) { AvpRepresentation avpChild = avpChilds.get(n); if (avpChild.getName().equals(newAvp.getName())) { try { AvpRepresentationImpl strongAvp = (AvpRepresentationImpl) newAvp.clone(); strongAvp.setMultiplicityIndicator(avpChild.getMultiplicityIndicator()); strongAvp.markFixPosition(avpChild.getPositionIndex()); strongAvp.markWeak(false); avpChilds.set(n, strongAvp); resolveWeakLinks(avp); } catch (CloneNotSupportedException cnse) { // It should not happen, but anyway if (logger.isWarnEnabled()) { logger.warn("Unable to clone AVP " + newAvp, cnse); } } } } } } } /** * @param doc * @param nameToCode * @param avpMap * @return */ private void parseCommands(Document doc) { // here all grouped AVPs should have proper filling. // now lets go through message definition, we have to respect application nodes NodeList applicationNodes = doc.getElementsByTagName("application"); // Map commandMap = new // HashMap(); for (int applicationIndex = 0; applicationIndex < applicationNodes.getLength(); applicationIndex++) { if (applicationNodes.item(applicationIndex).getNodeType() == Node.ELEMENT_NODE) { Element applicationElement = (Element) applicationNodes.item(applicationIndex); if (!applicationElement.hasAttribute("id")) { logger.debug("[ERROR] Application definition does not have ID, skipping message"); continue; } long applicationCode = Long.valueOf(applicationElement.getAttribute("id")); NodeList commandNodes = applicationElement.getElementsByTagName("command"); for (int c = 0; c < commandNodes.getLength(); c++) { Node commandNode = commandNodes.item(c); if (commandNode.getNodeType() == Node.ELEMENT_NODE) { Element commandElement = (Element) commandNode; if (!commandElement.hasAttribute("request")) { logger.debug( "[ERROR] Command for application: {} does not define if its request or answer, skipping.", applicationCode); continue; } String commandName = commandElement.getAttribute("name"); String commandCode = commandElement.getAttribute("code"); String isRequest = commandElement.getAttribute("request"); MessageRepresentationImpl msg = new MessageRepresentationImpl(Integer.valueOf(commandCode), applicationCode, Boolean.parseBoolean(isRequest), commandName); Map commandAvpList = new HashMap(); commandMap.put(msg, msg); // now we have to process avp defs for this message :) NodeList commandAvpsList = commandElement.getElementsByTagName("avp"); for (int commandAvpIndex = 0; commandAvpIndex < commandAvpsList.getLength(); commandAvpIndex++) { if (commandAvpsList.item(commandAvpIndex).getNodeType() == Node.ELEMENT_NODE) { Element commandAvpElement = (Element) commandAvpsList.item(commandAvpIndex); String multiplicity = null; String name = null; String index = null; if (!commandAvpElement.hasAttribute("name")) { logger.debug( "[ERROR] Command defines avp without name! Command: {}, Code: {}, ApplicationID: {}", new Object[]{msg.getName(), msg.getCommandCode(), msg.getApplicationId()}); continue; } else { name = commandAvpElement.getAttribute("name"); } if (!commandAvpElement.hasAttribute("multiplicity")) { logger.debug("[WARN] Command defines avp without multiplicity."); multiplicity = AvpRepresentation._MP_ZERO_OR_MORE; } else { multiplicity = commandAvpElement.getAttribute("multiplicity"); } index = commandAvpElement.hasAttribute("index") ? commandAvpElement.getAttribute("index") : "-1"; String avpCode = commandAvpElement.getAttribute("code"); String avpVendor = commandAvpElement.getAttribute("vendor"); if (avpCode == null) { logger.debug( "[ERROR] Command defines avp without code! Command: {}, Code: {}, ApplicationID: {}", new Object[]{msg.getName(), msg.getCommandCode(), msg.getApplicationId()}); continue; } if (avpVendor == null) { logger.debug( "[WARN] Command defines avp without vendor, assuming default. Command: {}, Code: {}, ApplicationID: {}", new Object[]{msg.getName(), msg.getCommandCode(), msg.getApplicationId()}); avpVendor = "0"; } // here we have name and multiplicity. we have to get avp def from name, clone and set multiplicity. AvpRepresentation strongRepresentation = null; AvpRepresentation strongKey = getMapKey(Integer.valueOf(avpCode), Long.valueOf(avpVendor)); strongRepresentation = this.avpMap.get(strongKey); if (strongRepresentation != null && !strongRepresentation.isWeak()) { AvpRepresentationImpl clone; try { clone = (AvpRepresentationImpl) strongRepresentation.clone(); clone.setMultiplicityIndicator(multiplicity); clone.markFixPosition(Integer.valueOf(index)); commandAvpList.put(clone, clone); } catch (CloneNotSupportedException cnse) { // It should not happen, but anyway if (logger.isWarnEnabled()) { logger.warn("Unable to clone AVP " + strongRepresentation, cnse); } } } else { logger.debug("[WARN] No strong avp for key {}, in name: {}", new Object[]{strongKey, name}); continue; } } } msg.setMessageAvps(commandAvpList); } } } } } /* * (non-Javadoc) * * @see org.jdiameter.api.validation.Dictionary#isConfigured() */ @Override public boolean isConfigured() { return this.configured; } @Override public AvpRepresentation getAvp(int code) { return getAvp(code, 0); } @Override public AvpRepresentation getAvp(int code, long vendorId) { if (!this.configured) { return null; } AvpRepresentation avp = avpMap.get(getMapKey(code, vendorId)); if (avp == null) { logger.warn("AVP with code {} and Vendor-Id {} not present in dictionary!", code, vendorId); } return avp; } @Override public AvpRepresentation getAvp(String avpName) { return this.configured ? avpByNameMap.get(avpName) : null; } private long getVendorCode(String vendorId) { long value = -1; if (vendorId == null) { value = 0; } else { String vendorCode = vendorMap.get(vendorId); value = vendorCode == null ? 0 : Long.parseLong(vendorCode); } return value; } private AvpRepresentation getMapKey(int avpCode, long vendorId) { return new AvpRepresentationImpl(avpCode, vendorId); } /* * (non-Javadoc) * * @see org.jdiameter.api.validation.Dictionary#getMessage(int, boolean) */ @Override public MessageRepresentation getMessage(int commandCode, boolean isRequest) { return this.getMessage(commandCode, 0, isRequest); } /* * (non-Javadoc) * * @see org.jdiameter.api.validation.Dictionary#getMessage(int, long, boolean) */ @Override public MessageRepresentation getMessage(int commandCode, long applicationId, boolean isRequest) { if (!this.configured) { return null; } MessageRepresentation key = new MessageRepresentationImpl(commandCode, applicationId, isRequest); return this.commandMap.get(key); } // Validation --------------------------------------------------------------- private boolean enabled = true; private ValidatorLevel sendValidationLevel = ValidatorLevel.ALL; private ValidatorLevel receiveValidationLevel = ValidatorLevel.OFF; /* * (non-Javadoc) * * @see org.jdiameter.api.validation.Dictionary#isValidate() */ @Override public boolean isEnabled() { return this.enabled; } /* * (non-Javadoc) * * @see org.jdiameter.api.validation.Dictionary#getSendLevel() */ @Override public ValidatorLevel getSendLevel() { return this.sendValidationLevel; } /* * (non-Javadoc) * * @see org.jdiameter.api.validation.Dictionary#getReceiveLevel() */ @Override public ValidatorLevel getReceiveLevel() { return this.receiveValidationLevel; } @Override public void setSendLevel(ValidatorLevel level) { this.sendValidationLevel = level; } @Override public void setReceiveLevel(ValidatorLevel level) { this.receiveValidationLevel = level; } @Override public void setEnabled(boolean enabled) { this.enabled = enabled; } public void setConfigured(boolean configured) { this.configured = configured; } @Override public void validate(Message msg, boolean incoming) throws AvpNotAllowedException { if (!enabled || !configured) { return; } MessageRepresentationImpl rep = new MessageRepresentationImpl(msg.getCommandCode(), msg.getApplicationId(), msg.isRequest()); rep = (MessageRepresentationImpl) this.commandMap.get(rep); if (rep == null) { // no notion, lets leave it. logger.warn("Validation could not be performed, command not defined!. Code={}, Application-Id={}, Req={}", new Object[]{msg.getCommandCode(), msg.getApplicationId(), msg.isRequest()}); return; } rep.validate(msg, (incoming ? receiveValidationLevel : sendValidationLevel)); } // Helper methods ----------------------------------------------------------- public Map getAvpMap() { return avpMap; } public Map getVendorMap() { return vendorMap; } public Map getCommandMap() { return commandMap; } public Map getTypedefMap() { return typedefMap; } public Map getNameToCodeMap() { return avpByNameMap; } protected void printAvpTree(AvpRepresentation rep, String tab) { String x = tab + "+-- " + rep.getCode() + "/" + rep.getVendorId(); while (x.length() < 25) { x += "."; } System.out.println(x + rep.getName() + " > " + rep.getType()); if (rep.isGrouped()) { for (AvpRepresentation repC : rep.getChildren()) { printAvpTree(repC, " " + tab); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/validation/MessageRepresentationImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.common.impl.validation; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Message; import org.jdiameter.api.validation.AvpNotAllowedException; import org.jdiameter.api.validation.AvpRepresentation; import org.jdiameter.api.validation.MessageRepresentation; import org.jdiameter.api.validation.ValidatorLevel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class represents message/command in validation framework. It contains basic info about command along with avp * list - their multiplicity and allowance. * * @author Bartosz Baranowski * @author Alexandre Mendonca * @since 1.5.4.0-build404 */ @SuppressWarnings("all") //3rd party lib public class MessageRepresentationImpl implements MessageRepresentation { private static transient Logger logger = LoggerFactory.getLogger(MessageRepresentationImpl.class); private int commandCode = -1; private long applicationId = 0; private boolean isRequest = false; protected Map unmuttableMessageAvps = new HashMap(); private String name = null; public MessageRepresentationImpl(int commandCode, long applicationId, boolean isRequest) { super(); this.commandCode = commandCode; this.applicationId = applicationId; this.isRequest = isRequest; } public MessageRepresentationImpl(int commandCode, boolean isRequest) { this(commandCode, 0, isRequest); } public MessageRepresentationImpl(int commandCode, long applicationId, boolean isRequest, String name) { super(); this.commandCode = commandCode; this.applicationId = applicationId; this.isRequest = isRequest; this.name = name; } public MessageRepresentationImpl(MessageRepresentationImpl clone) { super(); this.applicationId = clone.applicationId; this.commandCode = clone.commandCode; this.isRequest = clone.isRequest; this.name = clone.name; // TODO: copy avps? } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (applicationId ^ (applicationId >>> 32)); result = prime * result + commandCode; result = prime * result + (isRequest ? 1231 : 1237); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } MessageRepresentationImpl other = (MessageRepresentationImpl) obj; if (applicationId != other.applicationId) { return false; } if (commandCode != other.commandCode) { return false; } if (isRequest != other.isRequest) { return false; } return true; } @Override public Map getMessageAvps() { return unmuttableMessageAvps; } public void setMessageAvps(Map messageAvps) { //this.unmuttableMessageAvps = Collections.unmodifiableMap(messageAvps); this.unmuttableMessageAvps = messageAvps; } @Override public int getCommandCode() { return commandCode; } @Override public long getApplicationId() { return applicationId; } @Override public boolean isRequest() { return isRequest; } @Override public String getName() { return name; } @Override public AvpRepresentation getAvp(int code) { return getAvp(code, 0); } @Override public AvpRepresentation getAvp(int code, long vendorId) { AvpRepresentation avp = unmuttableMessageAvps.get(new AvpRepresentationImpl(code, vendorId)); if (avp == null) { logger.warn("AVP with code " + code + " and Vendor-Id " + vendorId + " not present in Message Representation!"); } return avp; } // Convenience methods ------------------------------------------------------ @Override public boolean isAllowed(int code, long vendorId) { AvpRepresentation avpRep = new AvpRepresentationImpl(code, vendorId); avpRep = this.unmuttableMessageAvps.get(avpRep); if (avpRep == null) { return true; } return avpRep.isAllowed(); } @Override public boolean isAllowed(int code) { return this.isAllowed(code, 0); } @Override public boolean isCountValidForMultiplicity(int code, int avpCount) { return this.isCountValidForMultiplicity(code, 0, avpCount); } @Override public boolean isCountValidForMultiplicity(int code, long vendorId, int avpCount) { AvpRepresentation avpRep = getAvp(code, vendorId); if (avpRep == null) { return true; } return avpRep.isCountValidForMultiplicity(avpCount); } @Override public boolean isCountValidForMultiplicity(AvpSet destination, int code, long vendorId) { return this.isCountValidForMultiplicity(destination, code, vendorId, 0); } @Override public boolean isCountValidForMultiplicity(AvpSet destination, int code) { return this.isCountValidForMultiplicity(destination, code, 0L); } @Override public boolean isCountValidForMultiplicity(AvpSet destination, int code, long vendorId, int numberToAdd) { AvpRepresentation avpRep = getAvp(code, vendorId); if (avpRep == null) { return true; } return avpRep.isCountValidForMultiplicity(destination, numberToAdd); } @Override public boolean isCountValidForMultiplicity(AvpSet destination, int code, int numberToAdd) { return this.isCountValidForMultiplicity(destination, code, 0, numberToAdd); } /* * (non-Javadoc) * * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(MessageRepresentation o) { if (o == this) { return 0; } if (o == null) { return 1; } return this.hashCode() - o.hashCode(); } @Override public Object clone() throws CloneNotSupportedException { MessageRepresentationImpl clone = (MessageRepresentationImpl) super.clone(); clone.applicationId = this.applicationId; clone.commandCode = this.commandCode; clone.isRequest = this.isRequest; clone.name = this.name; // clone.messageAvps = new HashMap(); Map map = new HashMap(); for (Entry entry : this.unmuttableMessageAvps.entrySet()) { map.put((AvpRepresentation) entry.getKey().clone(), (AvpRepresentation) entry.getValue().clone()); } clone.setMessageAvps(map); return clone; } @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append(isRequest ? "Request" : "Answer").append(" code: ").append(this.commandCode).append(" applicationId: ") .append(this.applicationId) .append(" name: ").append(this.name); for (AvpRepresentation childAvp : this.getMessageAvps().values()) { sb.append("\n").append(childAvp.toString()); } return sb.toString(); } // Validation part ---------------------------------------------------------- @Override public void validate(Message msg, ValidatorLevel validatorLevel) throws AvpNotAllowedException { if (validatorLevel == ValidatorLevel.OFF) { return; } // if its !OFF, we will go down, at least to this section for (AvpRepresentation ap : this.unmuttableMessageAvps.values()) { AvpSet innerSet = msg.getAvps().getAvps(ap.getCode(), ap.getVendorId()); int count = 0; if (innerSet != null) { count = innerSet.size(); } if (!ap.isCountValidForMultiplicity(count)) { throw new AvpNotAllowedException("AVP: \n" + ap + "\n, has wrong count in message - " + (count), ap.getCode(), ap.getVendorId()); } // if its ALL, we need to go down deeper in AVPs if (validatorLevel != ValidatorLevel.ALL) { continue; } if (count != 0 && ap.isGrouped()) { // we are grouped validateGrouped(ap, innerSet); } } } /** * @param ap * @param innerSet */ private void validateGrouped(AvpRepresentation ap, AvpSet innerSet) { // we have set of grouped avps, and ap is grouped, lets validate // NOTE this methods can be called multiple time, until we dont have for (int index = 0; index < innerSet.size(); index++) { Avp presumablyGrouped = innerSet.getAvpByIndex(index); ap.validate(presumablyGrouped); // AvpSet groupedPart = null; // try { // groupedPart = presumablyGrouped.getGrouped(); // } // catch (AvpDataException e) { // logger.debug("Failed to get grouped AVP.", e); // } // // if (groupedPart == null) { // logger.error("Avp should be grouped, but its not: " + ap); // // continue; // } // else { // validateGroupedChildren(ap, groupedPart); // } } } // /** // * @param ap // * @param presumablyGrouped // */ // private void validateGroupedChildren(AvpRepresentation ap, AvpSet groupedAvp) { // // we have grouped avp, and its representation, we should validate // // children. // for (AvpRepresentation childrenVAvp : ap.getChildren()) { // AvpSet childSset = groupedAvp.getAvps(childrenVAvp.getCode(), childrenVAvp.getVendorId()); // int count = childSset.size(); // // if (!childrenVAvp.isCountValidForMultiplicity(count)) { // throw new AvpNotAllowedException("AVP: " + childrenVAvp + " has wrong count, in grouped parent avp - " + (count) + ", allowed: " // + childrenVAvp.getMultiplicityIndicator(), ap.getCode(), ap.getVendorId()); // } // if (childrenVAvp.isGrouped()) { // // validateGrouped(childrenVAvp, childSset); // } // // else we are good ? // } // // } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/IFsmFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.client.api.fsm.IContext; import org.jdiameter.common.api.concurrent.IConcurrentFactory; /** * Peer FSM factory * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IFsmFactory extends org.jdiameter.client.api.fsm.IFsmFactory { // todo move to common api @Override IStateMachine createInstanceFsm(IContext context, IConcurrentFactory concurrentFactory, Configuration config) throws InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/IMetaData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api; import org.jdiameter.api.ApplicationId; /** * This interface describe extends methods of base class * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IMetaData extends org.jdiameter.client.api.IMetaData { /** * Add new Application Id to support application list * * @param applicationId applicationId */ void addApplicationId(ApplicationId applicationId); /** * Remove Application id from support application list * * @param applicationId applicationId */ void remApplicationId(ApplicationId applicationId); /** * @deprecated Reload parameters */ @Deprecated void reload(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/IMutablePeerTable.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api; import org.jdiameter.api.MutablePeerTable; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.api.controller.IPeerTable; /** * This interface describe extends methods of base class * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IMutablePeerTable extends MutablePeerTable, IPeerTable { /** * Check message on duplicate * * @param request checked message * * @return true if messahe has duplicate into storage */ IMessage isDuplicate(IMessage request); /** * Save message to duplicate storage * * @param key key of message * @param answer message */ void saveToDuplicate(String key, IMessage answer); /** * Return instance of session factory * * @return instance of session factory */ ISessionFactory getSessionFactory(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/INetwork.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api; import org.jdiameter.api.Network; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.client.api.IMessage; /** * This interface append to base interface some special methods. * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface INetwork extends Network { /** * Return NetworkListener instance for specified application-id * * @param message message * * @return NetworkListener instance for specified selector * * @see org.jdiameter.api.NetworkReqListener */ NetworkReqListener getListener(IMessage message); /** * This method set peer manager for addPeer/remPeer methods * * @param manager PeerTable instance */ void setPeerManager(IMutablePeerTable manager); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/IOverloadManager.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.OverloadManager; import org.jdiameter.api.URI; /** * This interface describe extends methods of base class * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IOverloadManager extends OverloadManager { /** * Return true if application has overload * * @param appId application id * * @return true if application has overload */ boolean isParenAppOverload(final ApplicationId appId); /** * eturn true if application has overload by predefined type * * @param appId application id * @param type type of overload (CPU, Memory... ) * * @return true if application has overload */ boolean isParenAppOverload(final ApplicationId appId, int type); /** * Notification about overload * * @param index overload entry index * @param uri peer uri * @param value overload value */ void changeNotification(int index, URI uri, double value); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/IPeer.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api; import org.jdiameter.client.api.fsm.IContext; import org.jdiameter.client.api.io.IConnection; /** * This interface describe extends methods of base class * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IPeer extends org.jdiameter.client.api.controller.IPeer { /** * Return true if peer must start reconnect procedure * * @return true if peer must start reconnect procedure */ boolean isAttemptConnection(); /** * Return action context * * @return action context */ IContext getContext(); /** * Return peer connection * * @return peer connection */ IConnection getConnection(); /** * Add new network connection (wait CER/CEA) * * @param conn new network connection */ void addIncomingConnection(IConnection conn); /** * Set result of election * * @param isElection result of election */ void setElection(boolean isElection); /** * Set overload manager * * @param ovrManager overload manager */ void notifyOvrManager(IOverloadManager ovrManager); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/IRouter.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api; /** * This interface describe extends methods of base class * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IRouter extends org.jdiameter.client.api.router.IRouter { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/IStateMachine.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api; /** * This interface describe extends methods of base class * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IStateMachine extends org.jdiameter.client.api.fsm.IStateMachine { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/agent/IAgent.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api.agent; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.Request; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.controller.IRealm; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAgent extends /* NetworkReqListener, */ EventListener { /** * This method use for process new network requests. * * @param request request message * * @return answer immediate answer messsage. Method may return null and an Answer will be sent later on */ Answer processRequest(IRequest request, IRealm matchedRealm); //realm should be matched for all agents iirc, soooo :) } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/agent/IAgentConfiguration.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api.agent; import java.io.Serializable; import java.util.Properties; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; /** * Interface through which agent can access configuration options for realm. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IAgentConfiguration extends Serializable { Properties getProperties(); /** * Parse resource and return implementation. May return null if pased argument is null. * * @param agentConfiguration * * @return * * @throws InternalException */ IAgentConfiguration parse(String agentConfiguration) throws InternalException; /** * @param agentConfiguration * * @return */ IAgentConfiguration parse(Configuration agentConfiguration) throws InternalException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/agent/IProxy.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api.agent; /** * @author babass */ @SuppressWarnings("all") //3rd party lib public interface IProxy extends IAgent { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/agent/IRedirect.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api.agent; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IRedirect extends IAgent { /** * Default property name for redirect host usage. */ String RHU_PROPERTY = "rdr.host.usage"; int RHU_DONT_CACHE = 0; int RHU_ALL_SESSION = 1; int RHU_ALL_REALM = 2; int RHU_REALM_AND_APPLICATION = 3; int RHU_ALL_APPLICATION = 4; int RHU_ALL_HOST = 5; int RHU_ALL_USER = 6; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/io/INetworkConnectionListener.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api.io; import org.jdiameter.client.api.io.IConnection; /** * This interface allow notifies consumers about created connections * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface INetworkConnectionListener { /** * Invoked when an new connection created. * * @param connection created connections */ void newNetworkConnection(IConnection connection); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/io/INetworkGuard.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api.io; /** * This interface describe INetWorkConnectionListener consumer * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface INetworkGuard { /** * Append new listener * * @param listener listener instance */ void addListener(INetworkConnectionListener listener); /** * Remove listener * * @param listener listener instance */ void remListener(INetworkConnectionListener listener); /** * Release all attached resources (socket and etc) */ void destroy(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/api/io/ITransportLayerFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.api.io; import java.net.InetAddress; import org.jdiameter.client.api.io.TransportException; /** * Factory of Network Layer elements. This interface append to parent interface additional method for creating * INetWorkGuard guard instances. Additional parameters (Configuration, Parsers and etc) injection to instance over * constructor * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface ITransportLayerFactory extends org.jdiameter.client.api.io.ITransportLayerFactory { /** * Create INetworkGuard instance with predefined parameters * * @param inetAddress address of server socket * @param port port of server socket * * @return INetWorkGuard instance * * @throws TransportException */ INetworkGuard createNetworkGuard(InetAddress inetAddress, int port) throws TransportException; /** * Create INetworkGuard instance with predefined parameters * * @param inetAddress address of server socket * @param port port of server socket * @param listener event listener * * @return INetWorkGuard instance * * @throws TransportException */ INetworkGuard createNetworkGuard(InetAddress inetAddress, int port, INetworkConnectionListener listener) throws TransportException; /** * Create INetworkGuard instance with predefined parameters * * @param inetAddress address of server socket * @param port port of server socket * * @return INetWorkGuard instance * * @throws TransportException */ INetworkGuard createNetworkGuard(InetAddress[] inetAddress, int port) throws TransportException; /** * Create INetworkGuard instance with predefined parameters * * @param inetAddress address of server socket * @param port port of server socket * @param listener event listener * * @return INetWorkGuard instance * * @throws TransportException */ INetworkGuard createNetworkGuard(InetAddress[] inetAddress, int port, INetworkConnectionListener listener) throws TransportException; } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/MessageValidator.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpSet; import org.jdiameter.api.ResultCode; import org.jdiameter.client.api.IMessage; /** * This class provides check incoming/outgoing diameter messages. Check's rules consist into xml file. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class MessageValidator { public static final Result SUCCESS = new Result(null, ResultCode.SUCCESS); private boolean enable = true; public MessageValidator() { // todo load validator rules } /** * Enable validation functions */ public void enable() { enable = true; } /** * Disable validation functions */ public void disable() { enable = false; } /** * Return true if validation function is on * * @return true if validation function is on */ public boolean isEnable() { return enable; } /** * Validate message * * @param message message instance * * @return result of validation procedure */ public Result check(IMessage message) { if (message == null) { throw new IllegalArgumentException("Message is null"); } if (!enable) { return SUCCESS; } // todo return null; } public static class Result { private IMessage errorMessage; private long code = ResultCode.SUCCESS; Result(IMessage errorMessage, long code) { this.errorMessage = errorMessage; this.code = code; } /** * Return true if message is correct * * @return true if message is correct */ public boolean isOK() { return code == ResultCode.SUCCESS || code == ResultCode.LIMITED_SUCCESS; } /** * Return long value of result code * * @return long value of result code */ public long toLong() { return code; } /** * Create error answer message with Result-Code Avp * * @return error answer message */ public IMessage toMessage() { if (errorMessage != null && errorMessage.getAvps().getAvp(Avp.RESULT_CODE) == null) { errorMessage.getAvps().addAvp(Avp.RESULT_CODE, code); } return errorMessage; } /** * Create error answer message with Experemental-Result-Code Avp * * @param vendorId vendor id * * @return error answer message with Experemental-Result-Code Avp */ public IMessage toMessage(int vendorId) { if (errorMessage != null && errorMessage.getAvps().getAvp(297) == null) { // EXPERIMENTAL_RESULT = 297 AvpSet er = errorMessage.getAvps().addGroupedAvp(297); er.addAvp(Avp.VENDOR_ID, vendorId); er.addAvp(Avp.EXPERIMENTAL_RESULT_CODE, code); } return errorMessage; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/MetaDataImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl; import static org.jdiameter.client.impl.helpers.Parameters.OwnIPAddress; import static org.jdiameter.server.impl.helpers.Parameters.OwnIPAddresses; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.Configuration; import org.jdiameter.api.Network; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.PeerTable; import org.jdiameter.api.StackType; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.impl.helpers.IPConverter; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.server.api.IMetaData; import org.jdiameter.server.api.IMutablePeerTable; import org.jdiameter.server.api.INetwork; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class MetaDataImpl extends org.jdiameter.client.impl.MetaDataImpl implements IMetaData { private static final Logger logger = LoggerFactory.getLogger(MetaDataImpl.class); private final Object lock = new Object(); public MetaDataImpl(IContainer s) { super(s); } public MetaDataImpl(IContainer s, IStatisticManager factory) { super(s, factory); } @Override public StackType getStackType() { return StackType.TYPE_SERVER; } @Override protected IPeer newLocalPeer(IStatisticManager statisticFactory) { return new ServerLocalPeer(statisticFactory); } @Override public void addApplicationId(ApplicationId applicationId) { synchronized (lock) { if (appIds.contains(applicationId)) { return; } appIds.add(applicationId); } if (logger.isDebugEnabled()) { logger.debug("Adding application id of auth [{}] acct [{}] vendor [{}]", new Object[] { applicationId.getAuthAppId(), applicationId.getAcctAppId(), applicationId.getVendorId() }); } } @Override public void remApplicationId(ApplicationId applicationId) { synchronized (lock) { appIds.remove(applicationId); } if (logger.isDebugEnabled()) { logger.debug("Removing application id of auth [{}] acct [{}] vendor [{}]", new Object[] { applicationId.getAuthAppId(), applicationId.getAcctAppId(), applicationId.getVendorId() }); } } @Override public void reload() { // Reload common application ids from configuration synchronized (lock) { appIds.clear(); logger.debug("Clearing out application ids"); getLocalPeer().getCommonApplications(); // Reload ip addresses from configuration ((ServerLocalPeer) peer).resetAddresses(); peer.getIPAddresses(); } } protected class ServerLocalPeer extends ClientLocalPeer { protected INetwork net = null; protected IMutablePeerTable manager = null; protected ISessionFactory factory = null; // XXX: FT/HA // protected Map slc = null; Map peerRequests = new ConcurrentHashMap(); public ServerLocalPeer(IStatisticManager statisticFactory) { super(statisticFactory); } @Override public Set getCommonApplications() { Set set; synchronized (lock) { set = super.getCommonApplications(); } return set; } @Override public InetAddress[] getIPAddresses() { if (addresses.length == 0) { Configuration[] ipAddresses = stack.getConfiguration().getChildren(OwnIPAddresses.ordinal()); List list = new ArrayList(); if (ipAddresses != null) { for (Configuration address : ipAddresses) { if (address != null) { InetAddress iaddress = getAddress(address); if (iaddress != null) { list.add(iaddress); } } } } else { InetAddress address = getDefaultIpAddress(); if (address != null) { list.add(address); } } addresses = list.toArray(new InetAddress[list.size()]); } return addresses; } private InetAddress getAddress(Configuration configuration) { InetAddress rc; String address = configuration.getStringValue(OwnIPAddress.ordinal(), null); if (address == null || address.length() == 0) { rc = getDefaultIpAddress(); } else { try { rc = InetAddress.getByName(address); } catch (UnknownHostException e) { logger.debug("Unable to retrieve IP by Address [{}]", address, e); rc = IPConverter.InetAddressByIPv4(address); if (rc == null) { rc = IPConverter.InetAddressByIPv6(address); } if (rc == null) { rc = getDefaultIpAddress(); } } } return rc; } private InetAddress getDefaultIpAddress() { try { return InetAddress.getByName(getLocalPeer().getUri().getFQDN()); } catch (Exception e1) { logger.debug("Unable to retrieve IP by URI [{}]", getLocalPeer().getUri().getFQDN(), e1); try { return InetAddress.getLocalHost(); } catch (Exception e2) { logger.debug("Unable to retrieve IP for localhost", e2); } } return null; } // Local processing message @Override @SuppressWarnings("unchecked") public boolean sendMessage(IMessage message) throws TransportException, OverloadException { logger.debug("Sending Message in Server Local Peer"); try { if (net == null || manager == null) { try { logger.debug("Unwrapping network and manager"); net = (INetwork) stack.unwrap(Network.class); manager = (IMutablePeerTable) stack.unwrap(PeerTable.class); factory = manager.getSessionFactory(); // XXX: FT/HA // slc = manager.getSessionReqListeners(); } catch (Exception e) { logger.warn("Error initialising for message send", e); } } IMessage answer = null; if (message.isRequest()) { logger.debug("Message is a request"); message.setHopByHopIdentifier(peer.getHopByHopIdentifier()); peerRequests.put(message.getHopByHopIdentifier(), message); NetworkReqListener listener = net.getListener(message); if (listener != null) { // This is duplicate code from PeerImpl answer = manager.isDuplicate(message); if (answer != null) { logger.debug("Found message in duplicates. No need to invoke listener, will send previous answer."); answer.setProxiable(message.isProxiable()); answer.getAvps().removeAvp(Avp.PROXY_INFO); for (Avp avp : message.getAvps().getAvps(Avp.PROXY_INFO)) { answer.getAvps().addAvp(avp); } answer.setHopByHopIdentifier(message.getHopByHopIdentifier()); } else { String avpSessionId = message.getSessionId(); if (avpSessionId != null) { // XXX: FT/HA // NetworkReqListener sessionListener = slc.get(avpSessionId); NetworkReqListener sessionListener = sessionDataSource.getSessionListener(avpSessionId); if (sessionListener != null) { logger.debug( "Giving message to sessionListener to process as Session-Id AVP existed in message " + "and was used to get a session from Session DataSource"); answer = (IMessage) sessionListener.processRequest(message); } else { try { logger.debug("Giving message to listener to process. Listener was retrieved from net"); answer = (IMessage) listener.processRequest(message); if (answer != null) { manager.saveToDuplicate(message.getDuplicationKey(), answer); } } catch (Exception e) { logger.debug("Error during processing message by listener", e); } } } } } else { if (logger.isDebugEnabled()) { logger.debug("Unable to find handler {} for message {}", message.getSingleApplicationId(), message); } } if (answer != null) { if (logger.isDebugEnabled()) { logger.debug("Removing message with HbH Identifier [{}] from Peer Requests Map", message.getHopByHopIdentifier()); } peerRequests.remove(message.getHopByHopIdentifier()); } } else { if (logger.isDebugEnabled()) { logger.debug( "Message is an answer. Setting answer to the message and fetching message from Peer Requests Map using HbH Identifier [{}]", message.getHopByHopIdentifier()); } answer = message; message = peerRequests.get(answer.getHopByHopIdentifier()); } // Process answer if (message != null && !message.isTimeOut() && answer != null) { logger.debug("Clearing timer on message and notifying event listeners of receiving success message"); message.clearTimer(); message.setState(IMessage.STATE_ANSWERED); message.getEventListener().receivedSuccessMessage(message, answer); } return true; } catch (Exception e) { logger.warn("Unable to process message {}", message, e); } return false; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/MutablePeerTableImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl; import static org.jdiameter.client.impl.helpers.Parameters.*; import static org.jdiameter.common.api.concurrent.IConcurrentFactory.ScheduledExecServices.*; import static org.jdiameter.server.impl.helpers.Parameters.*; import java.io.IOException; import java.net.InetAddress; import java.net.URISyntaxException; import java.net.UnknownServiceException; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Configuration; import org.jdiameter.api.ConfigurationListener; import org.jdiameter.api.DisconnectCause; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.MetaData; import org.jdiameter.api.MutableConfiguration; import org.jdiameter.api.MutablePeerTable; import org.jdiameter.api.Network; import org.jdiameter.api.Peer; import org.jdiameter.api.PeerState; import org.jdiameter.api.PeerTableListener; import org.jdiameter.api.Realm; import org.jdiameter.api.Statistic; import org.jdiameter.api.URI; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.api.StackState; import org.jdiameter.client.api.controller.IRealm; import org.jdiameter.client.api.fsm.EventTypes; import org.jdiameter.client.api.io.IConnection; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.controller.PeerTableImpl; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.server.api.IFsmFactory; import org.jdiameter.server.api.IMutablePeerTable; import org.jdiameter.server.api.INetwork; import org.jdiameter.server.api.IOverloadManager; import org.jdiameter.server.api.IPeer; import org.jdiameter.server.api.io.INetworkConnectionListener; import org.jdiameter.server.api.io.INetworkGuard; import org.jdiameter.server.api.io.ITransportLayerFactory; import org.jdiameter.server.impl.helpers.EmptyConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class MutablePeerTableImpl extends PeerTableImpl implements IMutablePeerTable, ConfigurationListener { private static final Logger logger = LoggerFactory.getLogger(MutablePeerTableImpl.class); private static final int CONN_INVALIDATE_PERIOD = 60000; private static final int MAX_PEER_TABLE_SIZE = 10000; protected Configuration config; protected ISessionFactory sessionFactory; protected IFsmFactory fsmFactory; protected ITransportLayerFactory transportFactory; protected IMessageParser parser; protected org.jdiameter.server.api.IRouter router; // Duplicate handling ------------------------------------------------------- protected boolean duplicateProtection = false; protected int duplicateSize; protected long duplicateTimer; protected ScheduledExecutorService duplicationScheduler = null; protected ScheduledFuture duplicationHandler = null; protected ConcurrentHashMap storageAnswers = new ConcurrentHashMap(); protected boolean isAcceptUndefinedPeer = false; // Connections handling ----------------------------------------------------- private ConcurrentHashMap incConnections; private ScheduledExecutorService connScheduler; private ScheduledFuture connHandler; // Network management ------------------------------------------------------- protected INetworkGuard networkGuard; protected INetwork network; protected Set predefinedPeerTable; // Overload handling -------------------------------------------------------- protected IOverloadManager ovrManager; protected ScheduledExecutorService overloadScheduler = null; protected ScheduledFuture overloadHandler = null; protected PeerTableListener peerTableListener = null; protected IStatisticManager statisticFactory; private IContainer stack; protected class StorageEntry { private String duplicationKey; private long time = System.currentTimeMillis(); private IMessage answer; public StorageEntry(IMessage message) { answer = message; // duplicationKey = message.getDuplicationKey(); doesn't work because it's answer String[] originInfo = router.getRequestRouteInfo(answer); duplicationKey = message.getDuplicationKey(originInfo[0], message.getEndToEndIdentifier()); } public IMessage getMessage() { return answer; } public long getTime() { return time; } public String getDuplicationKey() { return duplicationKey; } } public MutablePeerTableImpl(Configuration config, MetaData metaData, IContainer stack, org.jdiameter.server.api.IRouter router, ISessionFactory sessionFactory, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, IMessageParser parser, INetwork network, IOverloadManager ovrManager, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory) { logger.debug("MutablePeerTableImpl is being created"); this.metaData = metaData; this.config = config; this.router = router; this.sessionFactory = sessionFactory; this.statisticFactory = statisticFactory; this.concurrentFactory = concurrentFactory; this.fsmFactory = fsmFactory; this.transportFactory = trFactory; this.parser = parser; this.network = network; this.ovrManager = ovrManager; this.network.setPeerManager(this); this.stack = stack; this.isAcceptUndefinedPeer = config.getBooleanValue(AcceptUndefinedPeer.ordinal(), false); this.duplicateProtection = config.getBooleanValue(DuplicateProtection.ordinal(), (Boolean) DuplicateProtection.defValue()); if (this.duplicateProtection) { this.duplicateTimer = config.getLongValue(DuplicateTimer.ordinal(), (Long) DuplicateTimer.defValue()); this.duplicateSize = config.getIntValue(DuplicateSize.ordinal(), (Integer) DuplicateSize.defValue()); } logger.debug("Duplicate Protection Configuration: Enabled? {}, Timer: {}, Size: {}", new Object[] { this.duplicateProtection, this.duplicateTimer, this.duplicateSize }); if (predefinedPeerTable == null) { predefinedPeerTable = new CopyOnWriteArraySet(); } if (config instanceof MutableConfiguration) { ((MutableConfiguration) config).addChangeListener(this); } logger.debug("MutablePeerTableImpl is starting initialisation by calling init on super class"); init(stack, router, config, metaData, fsmFactory, transportFactory, statisticFactory, concurrentFactory, parser); logger.debug("MutablePeerTableImpl has finished initialisation"); } @Override protected Peer createPeer(int rating, String uri, String ip, String portRange, MetaData metaData, Configuration globalConfig, Configuration peerConfig, org.jdiameter.client.api.fsm.IFsmFactory fsmFactory, org.jdiameter.client.api.io.ITransportLayerFactory transportFactory, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, IMessageParser parser) throws InternalException, TransportException, URISyntaxException, UnknownServiceException { logger.debug("Creating Peer for URI [{}]", uri); if (predefinedPeerTable == null) { logger.debug("Creating new empty predefined peer table"); predefinedPeerTable = new CopyOnWriteArraySet(); } logger.debug("Adding URI [{}] to predefinedPeerTable", uri); predefinedPeerTable.add(new URI(uri).getFQDN()); if (peerConfig.getBooleanValue(PeerAttemptConnection.ordinal(), false)) { logger.debug( "Peer at URI [{}] is configured to attempt a connection (acting as a client) and a new peer instance will be created and returned", uri); return newPeerInstance(rating, new URI(uri), ip, portRange, true, null, metaData, globalConfig, peerConfig, (IFsmFactory) fsmFactory, (ITransportLayerFactory) transportFactory, parser, statisticFactory, concurrentFactory); } else { logger.debug( "Peer at URI [{}] is configured to NOT attempt a connection (i.e. acting as a server) and null will be returned", uri); return null; } } protected IPeer newPeerInstance(int rating, URI uri, String ip, String portRange, boolean attCnn, IConnection connection, MetaData metaData, Configuration globalConfig, Configuration peerConfig, IFsmFactory fsmFactory, ITransportLayerFactory transportFactory, IMessageParser parser, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory) throws URISyntaxException, UnknownServiceException, InternalException, TransportException { logger.debug("Creating and returning a new Peer Instance for URI [{}].", uri); return new org.jdiameter.server.impl.PeerImpl( rating, uri, ip, portRange, attCnn, connection, this, (org.jdiameter.server.api.IMetaData) metaData, globalConfig, peerConfig, sessionFactory, fsmFactory, transportFactory, statisticFactory, concurrentFactory, parser, network, ovrManager, sessionDatasource); } @Override public void setPeerTableListener(PeerTableListener peerTableListener) { this.peerTableListener = peerTableListener; } @Override public boolean elementChanged(int i, Object data) { Configuration newConf = (Configuration) data; stopTimeOut = newConf.getLongValue(StopTimeOut.ordinal(), (Long) StopTimeOut.defValue()); duplicateTimer = newConf.getLongValue(DuplicateTimer.ordinal(), (Long) DuplicateTimer.defValue()); isAcceptUndefinedPeer = newConf.getBooleanValue(AcceptUndefinedPeer.ordinal(), false); return true; } public boolean isDuplicateProtection() { return duplicateProtection; } @Override public void start() throws IllegalDiameterStateException, IOException { // TODO: use parent method logger.debug("Starting MutablePeerTableImpl. Starting router, overload scheduler, connection check timer, etc."); router.start(); // Start overload manager overloadScheduler = concurrentFactory.getScheduledExecutorService(PeerOverloadTimer.name()); Runnable overloadTask = new Runnable() { @Override public void run() { if (ovrManager != null) { for (Peer p : peerTable.values()) { ((IPeer) p).notifyOvrManager(ovrManager); } } } }; overloadHandler = overloadScheduler.scheduleAtFixedRate(overloadTask, 0, 1, TimeUnit.SECONDS); // Start duplication protection procedure if (duplicateProtection) { duplicationScheduler = concurrentFactory.getScheduledExecutorService(DuplicationMessageTimer.name()); Runnable duplicateTask = new Runnable() { @Override public void run() { long now = System.currentTimeMillis(); if (logger.isDebugEnabled()) { logger.debug( "Running Duplicate Cleaning Task. Duplicate Storage size is: {}. Removing entries with time <= '{}'", storageAnswers.size(), now - duplicateTimer); } for (StorageEntry s : storageAnswers.values()) { if (s != null && s.getTime() + duplicateTimer <= now) { if (logger.isTraceEnabled()) { logger.trace("Duplicate Cleaning Task - Removing Entry with key '{}' and time '{}'", s.getDuplicationKey(), s.getTime()); } storageAnswers.remove(s.getDuplicationKey()); } else { if (logger.isTraceEnabled()) { logger.trace("Duplicate Cleaning Task - Skipping Entry with key '{}' and time '{}'", s.getDuplicationKey(), s.getTime()); } } } if (logger.isDebugEnabled()) { logger.debug( "Completed Duplicate Cleaning Task. New Duplicate Storage size is: {}. Total task runtime: {}ms", storageAnswers.size(), System.currentTimeMillis() - now); } } }; duplicationHandler = duplicationScheduler.scheduleAtFixedRate(duplicateTask, duplicateTimer, duplicateTimer, TimeUnit.MILLISECONDS); } // connScheduler = concurrentFactory.getScheduledExecutorService(ConnectionTimer.name()); Runnable connectionCheckTask = new Runnable() { @Override public void run() { Map connections = getIncConnections(); for (IConnection connection : connections.values()) { if (System.currentTimeMillis() - connection.getCreatedTime() >= CONN_INVALIDATE_PERIOD) { logger.debug("External connection released by timeout [{}]", connection.getKey()); try { connection.remAllConnectionListener(); connection.release(); } catch (IOException e) { logger.debug("Unable to release connection", e); } connections.remove(connection.getKey()); } } } }; connHandler = connScheduler.scheduleAtFixedRate(connectionCheckTask, CONN_INVALIDATE_PERIOD, CONN_INVALIDATE_PERIOD, TimeUnit.MILLISECONDS); // Start server socket try { logger.debug("Creating network guard"); networkGuard = createNetworkGuard(transportFactory); } catch (TransportException e) { // We want the root cause, that's what matters to us... Throwable t = e; while (t.getCause() != null) { t = t.getCause(); } Peer p = stack.getMetaData().getLocalPeer(); String ips = ""; for (InetAddress ip : p.getIPAddresses()) { ips += " " + ip.getHostAddress() + ":" + p.getUri().getPort(); } logger.error("Unable to create server socket for LocalPeer '{}' at{} ({}).", new Object[] { p.getUri().getFQDN(), ips, t.getMessage() }); logger.debug("Unable to create server socket", e); } // Connect to predefined peers for (Peer p : peerTable.values()) { try { if (((IPeer) p).isAttemptConnection()) { p.connect(); } } catch (Exception e) { logger.warn("Unable to start connect procedure for peer [" + p + "]", e); } } isStarted = true; } public Set getPredefinedPeerTable() { return predefinedPeerTable; } public ConcurrentHashMap getIncConnections() { if (incConnections == null) { incConnections = new ConcurrentHashMap(); } return incConnections; } private final Object regLock = new Object(); private INetworkGuard createNetworkGuard(final ITransportLayerFactory transportFactory) throws TransportException { return transportFactory.createNetworkGuard( metaData.getLocalPeer().getIPAddresses(), metaData.getLocalPeer().getUri().getPort(), new INetworkConnectionListener() { @Override public void newNetworkConnection(final IConnection connection) { //PCB added logging logger.debug("newNetworkConnection. connection [{}]", connection.getKey()); synchronized (regLock) { final IConnectionListener listener = new IConnectionListener() { @Override public void connectionOpened(String connKey) { logger.debug("Connection [{}] opened", connKey); } @Override @SuppressWarnings("unchecked") public void connectionClosed(String connKey, List notSended) { logger.debug("Connection [{}] closed", connKey); unregister(true); } @Override public void messageReceived(String connKey, IMessage message) { logger.debug("Message [{}] received to peer [{}]", message, connKey); if (message.isRequest() && message.getCommandCode() == Message.CAPABILITIES_EXCHANGE_REQUEST) { connection.remConnectionListener(this); IPeer peer = null; String host; try { host = message.getAvps().getAvp(Avp.ORIGIN_HOST).getDiameterIdentity(); logger.debug("Origin-Host in new received message is [{}]", host); } catch (AvpDataException e) { logger.warn("Unable to retrieve find Origin-Host AVP in CER", e); unregister(true); return; } String realm; try { realm = message.getAvps().getAvp(Avp.ORIGIN_REALM).getDiameterIdentity(); logger.debug("Origin-Realm in new received message is [{}]", realm); } catch (AvpDataException e) { logger.warn("Unable to retrieve find Origin-Realm AVP in CER", e); unregister(true); return; } boolean foundInPredefinedTable = false; // find into predefined table for (String fqdn : predefinedPeerTable) { if (logger.isDebugEnabled()) { logger.debug("Checking against entry in predefinedPeerTable with FQDN [{}]", fqdn); } if (fqdn.equals(host)) { if (logger.isDebugEnabled()) { logger.debug("{} == {}", fqdn, host); } peer = (IPeer) peerTable.get(fqdn); foundInPredefinedTable = true; // found but not init break; } else { if (logger.isDebugEnabled()) { logger.debug("{} != {}", fqdn, host); } } } // find in peer table for peer already connected to server but not removed if (peer == null) { logger.debug( "Peer with FQDN [{}] was not found in predefined peer table. Checking at (previously) connected peers table", host); peer = (IPeer) peerTable.get(host); if (peer != null) { logger.debug("Got peer for FQDN [{}]. Is connection open ? {}.", host, peer.hasValidConnection()); } else { logger.debug("Still haven't found peer for FQDN [{}]", host); } } if (peer != null) { //FIXME: define procedure when 'peer.getRealm() != realm' logger.debug("Add [{}] connection to peer [{}]", connection, peer); peer.addIncomingConnection(connection); try { logger.debug("Handle [{}] message on peer [{}]", message, peer); peer.handleMessage( message.isRequest() ? EventTypes.CER_EVENT : EventTypes.CER_EVENT, message, connKey); } catch (Exception e) { logger.debug("Unable to process CER message", e); } } else { if (isAcceptUndefinedPeer || foundInPredefinedTable) { try { int port = connection.getRemotePort(); boolean hostAsUri = config.getBooleanValue(UseUriAsFqdn.ordinal(), (Boolean) UseUriAsFqdn.defValue()); URI uri; if (hostAsUri || host.startsWith("aaa://")) { uri = new URI(host); } else { uri = new URI("aaa://" + host + ":" + port); } peer = newPeerInstance(0, uri, connection.getRemoteAddress().getHostAddress(), null, false, connection, metaData, config, null, fsmFactory, transportFactory, parser, statisticFactory, concurrentFactory); logger.debug("Created new peer instance [{}] and adding to peer table", peer); peer.setRealm(realm); Collection realms = router.getRealmTable().getRealms(realm); for (Realm r : realms) { if (r.getName().equals(realm)) { logger.debug( "Found the realm [{}] for the new peer [{}], adding it to it", realm, peer); ((IRealm) r).addPeerName(host); } } appendPeerToPeerTable(peer); logger.debug("Handle [{}] message on peer [{}]", message, peer); peer.handleMessage( message.isRequest() ? EventTypes.CER_EVENT : EventTypes.CER_EVENT, message, connKey); } catch (Exception e) { logger.warn("Unable to create peer", e); unregister(true); } } else { logger.info("Skip anonymous connection [{}]", connection); unregister(true); } } } else { logger.debug("Unknown message [{}] by connection [{}]", message, connKey); unregister(true); } } @Override public void internalError(String connKey, IMessage message, TransportException cause) { logger.debug("Connection [{}] internalError [{}]", connKey, cause); unregister(true); } public void unregister(boolean release) { getIncConnections().remove(connection.getKey()); connection.remConnectionListener(this); if (release && connection.isConnected()) { try { connection.release(); } catch (IOException e) { logger.debug("Unable to release connection [{}]", connection); } } } }; //PCB added logging String connKey = connection.getKey(); getIncConnections().put(connection.getKey(), connection); logger.debug("Inserted connection [{}] into IncConnections", connKey); connection.addConnectionListener(listener); logger.debug("Added listener [{}] to connection [{}]", listener, connKey); } } }); } private void appendPeerToPeerTable(IPeer peer) { logger.debug("Adding Peer[{}] to PeerTable with size {}", peer, peerTable.size()); // Cleaning up if we are at max capacity... if (peerTable.size() == MAX_PEER_TABLE_SIZE) { for (String k : peerTable.keySet()) { Peer p = peerTable.get(k); if (p != null && p.getState(PeerState.class) == PeerState.DOWN) { peerTable.remove(k, p); } } } peerTable.put(peer.getUri().getFQDN(), peer); if (peerTableListener != null) { peerTableListener.peerAccepted(peer); } } @Override public void stopping(int disconnectCause) { super.stopping(disconnectCause); if (networkGuard != null) { networkGuard.destroy(); networkGuard = null; } // if (overloadScheduler != null) { concurrentFactory.shutdownNow(overloadScheduler); overloadScheduler = null; overloadHandler.cancel(true); overloadHandler = null; } // if (duplicationScheduler != null) { concurrentFactory.shutdownNow(duplicationScheduler); duplicationScheduler = null; } if (duplicationHandler != null) { duplicationHandler.cancel(true); duplicationHandler = null; } // if (connScheduler != null) { concurrentFactory.shutdownNow(connScheduler); connScheduler = null; } if (connHandler != null) { connHandler.cancel(true); connHandler = null; } //remove incoming data storageAnswers.clear(); // Clear dynamic peers from peertable Iterator it = super.peerTable.keySet().iterator(); while (it.hasNext()) { String fqdn = it.next(); if (this.predefinedPeerTable.contains(fqdn)) { continue; } else { it.remove(); } } } @Override public Peer addPeer(URI peerURI, String realm, boolean connecting) { //TODO: add sKey here, now it adds peer to all realms. //TODO: better, separate addPeer from realm! try { Configuration peerConfig = null; Configuration[] peers = config.getChildren(PeerTable.ordinal()); // find peer config for (Configuration c : peers) { if (peerURI.getFQDN().equals(c.getStringValue(PeerName.ordinal(), ""))) { peerConfig = c; break; } } if (peerConfig == null) { peerConfig = new EmptyConfiguration(false).add(PeerAttemptConnection, connecting); } IPeer peer = (IPeer) createPeer(0, peerURI.toString(), null, null, metaData, config, peerConfig, fsmFactory, transportFactory, statisticFactory, concurrentFactory, parser); if (peer == null) { return null; } peer.setRealm(realm); appendPeerToPeerTable(peer); boolean found = false; Collection realms = this.router.getRealmTable().getRealms(realm); for (Realm r : realms) { if (r.getName().equals(realm)) { ((IRealm) r).addPeerName(peerURI.toString()); found = true; break; } } if (!found) { throw new IllegalArgumentException("Incorrect realm name"); } if (StackState.STARTED.equals(stack.getState()) && connecting) { peer.connect(); } return peer; } catch (Exception e) { logger.debug("Unable to add peer", e); return null; } } public Set getAllRealms() { return new HashSet(router.getRealmTable().getRealms()); } @Override public Peer removePeer(String host) { try { String fqdn = null; for (String f : peerTable.keySet()) { if (f.equals(host)) { fqdn = f; peerTable.get(fqdn).disconnect(DisconnectCause.BUSY); } } if (fqdn != null) { predefinedPeerTable.remove(fqdn); Peer removedPeer = peerTable.remove(fqdn); if (peerTableListener != null) { peerTableListener.peerRemoved(removedPeer); } return removedPeer; } else { return null; } } catch (Exception e) { logger.debug("Unable to remove peer", e); return null; } } @Override public Statistic getStatistic(String name) { for (Peer p : peerTable.values()) { if (p.getUri().getFQDN().equals(name)) { return ((IPeer) p).getStatistic(); } } return null; } @Override public IMessage isDuplicate(IMessage request) { String key = request.getDuplicationKey(); if (key != null && storageAnswers != null) { StorageEntry entry = storageAnswers.get(key); return entry != null ? (IMessage) entry.getMessage().clone() : null; } return null; } @Override public void saveToDuplicate(String key, IMessage answer) { if (storageAnswers != null && storageAnswers.size() < duplicateSize) { if (key != null) { StorageEntry se = new StorageEntry((IMessage) answer.clone()); if (logger.isTraceEnabled()) { logger.trace("Duplicate Protection - Inserting Entry with key '{}' and time '{}'", key, se.getTime()); } storageAnswers.put(key, se); } } } @Override public ISessionFactory getSessionFactory() { return sessionFactory; } @Override public boolean isWrapperFor(Class aClass) throws InternalException { boolean isWrapp = super.isWrapperFor(aClass); return aClass == MutablePeerTable.class || aClass == Network.class || isWrapp; } @Override public T unwrap(Class aClass) throws InternalException { if (aClass == MutablePeerTable.class) { return assembler.getComponentInstance(aClass); } if (aClass == Network.class) { return assembler.getComponentInstance(aClass); } return null; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/NetworkImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl; import java.util.Collection; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import org.jdiameter.api.ApplicationAlreadyUseException; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.InternalException; import org.jdiameter.api.LocalAction; import org.jdiameter.api.Message; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.Peer; import org.jdiameter.api.Realm; import org.jdiameter.api.Selector; import org.jdiameter.api.Statistic; import org.jdiameter.api.URI; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.jdiameter.server.api.IMetaData; import org.jdiameter.server.api.IMutablePeerTable; import org.jdiameter.server.api.INetwork; import org.jdiameter.server.api.IRouter; import org.jdiameter.server.api.agent.IAgentConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class NetworkImpl implements INetwork { private static final Logger logger = LoggerFactory.getLogger(NetworkImpl.class); protected IMutablePeerTable manager; protected IRouter router; protected IMetaData metaData; private final ApplicationId commonAuthAppId = ApplicationId.createByAuthAppId(0, 0xffffffff); private final ApplicationId commonAccAppId = ApplicationId.createByAccAppId(0, 0xffffffff); private final ConcurrentHashMap appIdToNetListener = new ConcurrentHashMap(); private final ConcurrentHashMap selectorToNetListener = new ConcurrentHashMap(); protected IStatistic statistic; public NetworkImpl(IStatisticManager statisticFactory, IMetaData metaData, IRouter router) { this.router = router; this.metaData = metaData; IStatisticRecord nrlStat = statisticFactory.newCounterRecord(IStatisticRecord.Counters.RequestListenerCount, new IStatisticRecord.IntegerValueHolder() { @Override public int getValueAsInt() { return appIdToNetListener.size(); } @Override public String getValueAsString() { return String.valueOf(getValueAsInt()); } }); IStatisticRecord nslStat = statisticFactory.newCounterRecord(IStatisticRecord.Counters.SelectorCount, new IStatisticRecord.IntegerValueHolder() { @Override public int getValueAsInt() { return selectorToNetListener.size(); } @Override public String getValueAsString() { return String.valueOf(getValueAsInt()); } }); //no need to remove, this class lives with whole stack, until its destroyed. statistic = statisticFactory.newStatistic("network", IStatistic.Groups.Network, nrlStat, nslStat); } @Override public void addNetworkReqListener(NetworkReqListener networkReqListener, ApplicationId... applicationId) throws ApplicationAlreadyUseException { for (ApplicationId a : applicationId) { if (appIdToNetListener.containsKey(commonAuthAppId) || appIdToNetListener.containsKey(commonAccAppId)) { throw new ApplicationAlreadyUseException(a + " already use by common application id"); } if (appIdToNetListener.containsKey(applicationId)) { throw new ApplicationAlreadyUseException(a + " already use"); } appIdToNetListener.put(a, networkReqListener); metaData.addApplicationId(a); // this has ALL config declared, we need currently deployed router.getRealmTable().addLocalApplicationId(a); } } @Override public void addNetworkReqListener(NetworkReqListener listener, Selector... selectors) { for (Selector s : selectors) { selectorToNetListener.put(s, listener); ApplicationId ap = s.getMetaData(); metaData.addApplicationId(ap); router.getRealmTable().addLocalApplicationId(ap); } } @Override public void removeNetworkReqListener(ApplicationId... applicationId) { for (ApplicationId a : applicationId) { appIdToNetListener.remove(a); for (Selector s : selectorToNetListener.keySet()) { if (s.getMetaData().equals(a)) { return; } } metaData.remApplicationId(a); router.getRealmTable().removeLocalApplicationId(a); } } @Override public void removeNetworkReqListener(Selector... selectors) { for (Selector s : selectors) { selectorToNetListener.remove(s); if (appIdToNetListener.containsKey(s.getMetaData())) { return; } for (Selector i : selectorToNetListener.keySet()) { if (i.getMetaData().equals(s.getMetaData())) { return; } } metaData.remApplicationId(s.getMetaData()); router.getRealmTable().removeLocalApplicationId(s.getMetaData()); } } public Peer addPeer(String name, String realm, boolean connecting) { if (manager != null) { try { return manager.addPeer(new URI(name), realm, connecting); } catch (Exception e) { logger.error( "Failed to add peer with name[" + name + "] and realm[" + realm + "] (connecting=" + connecting + ")", e); return null; } } else { logger.debug("Failed to add peer with name[{}] and realm[{}] (connecting={}) as peer manager is null.", new Object[] { name, realm, connecting }); return null; } } @Override public boolean isWrapperFor(Class aClass) throws InternalException { return false; } @Override public T unwrap(Class aClass) throws InternalException { return null; } public Realm addRealm(String name, ApplicationId applicationId, LocalAction localAction, String agentConfiguration, boolean dynamic, long expirationTime) { try { //TODO: why oh why this method exists? return router.getRealmTable().addRealm(name, applicationId, localAction, agentConfiguration, dynamic, expirationTime, new String[0]); } catch (InternalException e) { logger.error("Failure on add realm operation.", e); return null; } } public Realm addRealm(String name, ApplicationId applicationId, LocalAction localAction, IAgentConfiguration agentConfiguration, boolean dynamic, long expirationTime) { try { //TODO: why oh why this method exists? return router.getRealmTable().addRealm(name, applicationId, localAction, agentConfiguration, dynamic, expirationTime, new String[0]); } catch (InternalException e) { logger.error("Failure on add realm operation.", e); return null; } } public Collection remRealm(String name) { return router.getRealmTable().removeRealm(name); } @Override public Statistic getStatistic() { return this.statistic; } @Override public NetworkReqListener getListener(IMessage message) { if (message == null) { return null; } for (Selector s : selectorToNetListener.keySet()) { boolean r = s.checkRule(message); if (r) { return selectorToNetListener.get(s); } } ApplicationId appId = message.getSingleApplicationId(); if (appId == null) { return null; } if (appIdToNetListener.containsKey(commonAuthAppId)) { return appIdToNetListener.get(commonAuthAppId); } else if (appIdToNetListener.containsKey(commonAccAppId)) { return appIdToNetListener.get(commonAccAppId); } else { return appIdToNetListener.get(appId); } } @Override public void setPeerManager(IMutablePeerTable manager) { this.manager = manager; } public List getListPeers() { return manager.getPeerTable(); } public IRealmTable getRealmTable() { return this.router.getRealmTable(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/OverloadManagerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl; import static org.jdiameter.client.impl.helpers.Parameters.*; import static org.jdiameter.server.impl.helpers.Parameters.*; import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Configuration; import org.jdiameter.api.OverloadListener; import org.jdiameter.api.URI; import org.jdiameter.server.api.IOverloadManager; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class OverloadManagerImpl implements IOverloadManager { private ConcurrentLinkedQueue listeners = new ConcurrentLinkedQueue(); private ConcurrentHashMap appInfo = new ConcurrentHashMap(); public OverloadManagerImpl(Configuration config) { Configuration[] entries = config.getChildren(OverloadMonitor.ordinal()); if (entries == null) { return; } for (Configuration e : entries) { ApplicationId appId = null; Configuration[] cAppId = e.getChildren(ApplicationId.ordinal()); for (Configuration i : cAppId) { if (i.getLongValue(AuthApplId.ordinal(), 0) != 0) { appId = org.jdiameter.api.ApplicationId.createByAuthAppId( i.getLongValue(VendorId.ordinal(), 0), i.getLongValue(AuthApplId.ordinal(), 0)); } else { appId = org.jdiameter.api.ApplicationId.createByAccAppId( i.getLongValue(VendorId.ordinal(), 0), i.getLongValue(AcctApplId.ordinal(), 0)); } break; } if (appId == null) { continue; } AppOverloadInfo info = new AppOverloadInfo(appId); info.appendEntry( e.getIntValue(OverloadEntryIndex.ordinal(), 0), e.getDoubleValue(OverloadEntrylowThreshold.ordinal(), 0), e.getDoubleValue(OverloadEntryhighThreshold.ordinal(), 0)); appInfo.put(appId, info); } } @Override public void parentAppOverloadDetected(ApplicationId applicationId, int type, double value) { AppOverloadInfo app = appInfo.get(createKey(applicationId)); if (app != null) { app.updateInformation(type, value); } } @Override public void parentAppOverloadCeased(ApplicationId applicationId, int type) { AppOverloadInfo app = appInfo.get(createKey(applicationId)); if (app != null) { app.updateInformation(type, 0); } } private Object createKey(final ApplicationId appId) { return new Object() { @Override public int hashCode() { return appId.hashCode(); } @Override public boolean equals(Object obj) { return appId.equals(obj); } }; } @Override public boolean isParenAppOverload(final ApplicationId appId) { if (appId == null) { return false; } AppOverloadInfo app = appInfo.get(createKey(appId)); return app != null && app.isOverload(); } @Override public boolean isParenAppOverload(final ApplicationId appId, final int type) { AppOverloadInfo app = appInfo.get(createKey(appId)); return app != null && app.isOverload(type); } @Override public void addOverloadListener(OverloadListener overloadListener, double lowThreshold, double highThreshold, int qIndex) { listeners.add(new OverloadInfo(overloadListener, lowThreshold, highThreshold, qIndex)); } @Override public void removeOverloadListener(OverloadListener overloadListener, int qIndex) { listeners.remove(new OverloadInfo(overloadListener, qIndex)); } @Override public void changeNotification(int index, URI uri, double value) { for (OverloadInfo e : listeners) { if (e.getCode() == index) { e.changeNotification(uri, value); } } } public static class AppOverloadInfo { private ApplicationId appId; private ArrayList entries = new ArrayList(); private final Object lock = new Object(); public ApplicationId getAppId() { return appId; } public AppOverloadInfo(ApplicationId appId) { this.appId = appId; } public void appendEntry(int type, double lowThreshold, double highThreshold) { entries.add(new AppOverloadInfoEntry(type, lowThreshold, highThreshold)); } public boolean isOverload() { for (AppOverloadInfoEntry e : entries) { if (e.isOverload()) { return true; } } return false; } public boolean isOverload(int type) { for (AppOverloadInfoEntry e : entries) { if (e.getType() == type) { synchronized (lock) { if (e.isOverload()) { return true; } } } } return false; } public void updateInformation(int type, double threshold) { for (AppOverloadInfoEntry e : entries) { if (e.getType() == type) { synchronized (lock) { e.updateInformation(threshold); } } } } } public static class AppOverloadInfoEntry { private int type; private double lowThreshold, highThreshold; private double currentValue; private final Object lock = new Object(); public AppOverloadInfoEntry(int type, double lowThreshold, double highThreshold) { this.type = type; this.lowThreshold = lowThreshold; this.highThreshold = highThreshold; } public int getType() { return type; } public double getLowThreshold() { return lowThreshold; } public double getHighThreshold() { return highThreshold; } public double getCurrentValue() { return currentValue; } public void updateInformation(double threshold) { synchronized (lock) { this.currentValue = threshold; } } public boolean isOverload() { synchronized (lock) { return (currentValue >= lowThreshold && currentValue <= highThreshold); } } } public static class OverloadInfo { private OverloadListener overloadListener; private double lowThreshold, highThreshold; private int qIndex; private boolean isOverload; private Lock lock = new ReentrantLock(); public OverloadInfo(OverloadListener overloadListener, int qIndex) { this.overloadListener = overloadListener; this.qIndex = qIndex; } public OverloadInfo(OverloadListener overloadListener, double lowThreshold, double highThreshold, int qIndex) { this.overloadListener = overloadListener; this.lowThreshold = lowThreshold; this.highThreshold = highThreshold; this.qIndex = qIndex; } public void changeNotification(URI uri, double value) { if (value >= lowThreshold && value <= highThreshold) { overloadListener.overloadDetected(uri, value); lock.lock(); isOverload = true; lock.unlock(); } else { lock.lock(); if (isOverload) { overloadListener.overloadCeased(uri); isOverload = false; } lock.unlock(); } } public int getCode() { return qIndex; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } OverloadInfo that = (OverloadInfo) o; if (qIndex != that.qIndex) { return false; } if (overloadListener != null ? !overloadListener.equals(that.overloadListener) : that.overloadListener != null) { return false; } return true; } @Override public int hashCode() { int result; result = (overloadListener != null ? overloadListener.hashCode() : 0); result = 31 * result + qIndex; return result; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/PeerImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl; import org.jdiameter.api.*; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IMetaData; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.client.api.controller.IRealm; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.client.api.fsm.IContext; import org.jdiameter.client.api.io.IConnection; import org.jdiameter.client.api.io.ITransportLayerFactory; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.jdiameter.server.api.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.InetAddress; import java.util.Map; import java.util.Set; import static org.jdiameter.api.PeerState.DOWN; import static org.jdiameter.api.PeerState.INITIAL; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class PeerImpl extends org.jdiameter.client.impl.controller.PeerImpl implements IPeer { private static final Logger logger = LoggerFactory.getLogger(org.jdiameter.server.impl.PeerImpl.class); // External references private MutablePeerTableImpl peerTable; protected Set predefinedPeerTable; protected INetwork network; protected IOverloadManager ovrManager; protected ISessionFactory sessionFactory; // Internal parameters and members protected boolean isDuplicateProtection; protected boolean isAttemptConnection; protected boolean isElection = true; protected Map incConnections; /** * Create instance of class */ public PeerImpl(int rating, URI remotePeer, String ip, String portRange, boolean attCnn, IConnection connection, MutablePeerTableImpl peerTable, IMetaData metaData, Configuration config, Configuration peerConfig, ISessionFactory sessionFactory, IFsmFactory fsmFactory, ITransportLayerFactory trFactory, IStatisticManager statisticFactory, IConcurrentFactory concurrentFactory, IMessageParser parser, INetwork nWork, IOverloadManager oManager, final ISessionDatasource sessionDataSource) throws InternalException, TransportException { super(peerTable, rating, remotePeer, ip, portRange, metaData, config, peerConfig, fsmFactory, trFactory, parser, statisticFactory, concurrentFactory, connection, sessionDataSource); // Create specific action context this.peerTable = peerTable; this.isDuplicateProtection = this.peerTable.isDuplicateProtection(); this.sessionFactory = sessionFactory; this.isAttemptConnection = attCnn; this.incConnections = this.peerTable.getIncConnections(); this.predefinedPeerTable = this.peerTable.getPredefinedPeerTable(); this.network = nWork; this.ovrManager = oManager; } @Override protected void createPeerStatistics() { super.createPeerStatistics(); // Append fsm statistic if (this.fsm instanceof IStateMachine) { StatisticRecord[] records = ((IStateMachine) fsm).getStatistic().getRecords(); IStatisticRecord[] recordsArray = new IStatisticRecord[records.length]; int count = 0; for (StatisticRecord st : records) { recordsArray[count++] = (IStatisticRecord) st; } this.statistic.appendCounter(recordsArray); } } protected void preProcessRequest(IMessage message) { // ammendonca: this is non-sense, we don't want to save requests //if (isDuplicateProtection && message.isRequest()) { // peerTable.saveToDuplicate(message.getDuplicationKey(), message); //} } @Override public boolean isAttemptConnection() { return isAttemptConnection; } @Override public IContext getContext() { return new LocalActionConext(); } @Override public IConnection getConnection() { return connection; } @Override public void addIncomingConnection(IConnection conn) { PeerState state = fsm.getState(PeerState.class); if (DOWN == state || INITIAL == state) { conn.addConnectionListener(connListener); // ammendonca: if we are receiving a new connection in such state, we may want to make it primary, right? this.connection = conn; logger.debug("Append external connection [{}]", conn.getKey()); } else { logger.debug("Releasing connection [{}]", conn.getKey()); incConnections.remove(conn.getKey()); try { conn.release(); } catch (IOException e) { logger.debug("Can not close external connection", e); } finally { logger.debug("Close external connection"); } } } @Override public void setElection(boolean isElection) { this.isElection = isElection; } @Override public void notifyOvrManager(IOverloadManager ovrManager) { ovrManager.changeNotification(0, getUri(), fsm.getQueueInfo()); } @Override public String toString() { if (fsm != null) { return "SPeer{" + "Uri=" + uri + "; State=" + fsm.getState(PeerState.class) + "; con=" + connection + "; incCon" + incConnections + " }"; } return "SPeer{" + "Uri=" + uri + "; State=" + fsm + "; con=" + connection + "; incCon" + incConnections + " }"; } protected class LocalActionConext extends ActionContext { @Override public void sendCeaMessage(int resultCode, Message cer, String errMessage) throws TransportException, OverloadException { logger.debug("Send CEA message"); IMessage message = parser.createEmptyMessage(Message.CAPABILITIES_EXCHANGE_ANSWER, 0); message.setRequest(false); message.setHopByHopIdentifier(cer.getHopByHopIdentifier()); message.setEndToEndIdentifier(cer.getEndToEndIdentifier()); message.getAvps().addAvp(Avp.ORIGIN_HOST, metaData.getLocalPeer().getUri().getFQDN(), true, false, true); message.getAvps().addAvp(Avp.ORIGIN_REALM, metaData.getLocalPeer().getRealmName(), true, false, true); for (InetAddress ia : metaData.getLocalPeer().getIPAddresses()) { message.getAvps().addAvp(Avp.HOST_IP_ADDRESS, ia, true, false); } message.getAvps().addAvp(Avp.VENDOR_ID, metaData.getLocalPeer().getVendorId(), true, false, true); for (ApplicationId appId : metaData.getLocalPeer().getCommonApplications()) { addAppId(appId, message); } message.getAvps().addAvp(Avp.PRODUCT_NAME, metaData.getLocalPeer().getProductName(), false); message.getAvps().addAvp(Avp.RESULT_CODE, resultCode, true, false, true); message.getAvps().addAvp(Avp.FIRMWARE_REVISION, metaData.getLocalPeer().getFirmware(), true); if (errMessage != null) { message.getAvps().addAvp(Avp.ERROR_MESSAGE, errMessage, false); } sendMessage(message); } @Override public int processCerMessage(String key, IMessage message) { logger.debug("Processing CER"); int resultCode = ResultCode.SUCCESS; try { if (connection == null || !connection.isConnected()) { if (logger.isDebugEnabled()) { logger.debug( "Connection is null or not connected. Looking for one in incConnections with key [{}]. Here are the incConnections :", key); for (String c : incConnections.keySet()) { logger.debug(c); } } connection = incConnections.get(key); } // Process cer Set newAppId = getCommonApplicationIds(message); if (newAppId.isEmpty()) { if (logger.isWarnEnabled()) { logger.warn("Processing CER failed for [{}], no common application. Message AppIds [{}]", getUri(), message.getApplicationIdAvps()); } return ResultCode.NO_COMMON_APPLICATION; } // Handshake if (!connection.getKey().equals(key)) { // received cer by other connection logger.debug("CER received by other connection [{}]", key); switch (fsm.getState(PeerState.class)) { case DOWN: resultCode = ResultCode.SUCCESS; break; case INITIAL: boolean isLocalWin = false; if (isElection) { try { // ammendonca: can't understand why it checks for <= 0 ... using equals //isLocalWin = metaData.getLocalPeer().getUri().getFQDN().compareTo( // message.getAvps().getAvp(Avp.ORIGIN_HOST).getOctetString()) <= 0; isLocalWin = metaData.getLocalPeer().getUri().getFQDN().equals( message.getAvps().getAvp(Avp.ORIGIN_HOST).getOctetString()); } catch (Exception exc) { isLocalWin = true; } } logger.debug("local peer is win - [{}]", isLocalWin); resultCode = 0; if (isLocalWin) { IConnection c = incConnections.get(key); c.remConnectionListener(connListener); c.disconnect(); incConnections.remove(key); } else { connection.disconnect(); // close current connection and work with other connection connection.remConnectionListener(connListener); connection = incConnections.remove(key); resultCode = ResultCode.SUCCESS; } break; } } else { if (logger.isDebugEnabled()) { logger.debug("CER received by current connection, key: [{}] PeerState: [{}] ", key, fsm.getState(PeerState.class)); } if (fsm.getState(PeerState.class).equals(INITIAL)) { // received cer by current connection resultCode = 0; // NOP } incConnections.remove(key); } if (resultCode == ResultCode.SUCCESS) { commonApplications.clear(); commonApplications.addAll(newAppId); fillIPAddressTable(message); } } catch (Exception exc) { logger.debug("Can not process CER", exc); } logger.debug("CER result [{}]", resultCode); return resultCode; } @Override public boolean isRestoreConnection() { return isAttemptConnection; } @Override public String getPeerDescription() { return PeerImpl.this.toString(); } private boolean processMessage(IMessage message) { boolean isProcessed = false; // this is for handling possible REDIRECT, destRealm != local.realm LocalAction action = null; IRealm matched = null; IRealmTable realmTable = router.getRealmTable(); matched = (IRealm) realmTable.matchRealm(message); if (matched != null) { action = matched.getLocalAction(); } else { // We don't support it locally, its not defined as remote, so send no such realm answer. sendErrorAnswer(message, null, ResultCode.APPLICATION_UNSUPPORTED); // or REALM_NOT_SERVED ? return true; } switch (action) { case LOCAL: // always call listener - this covers realms // configured as localy processed and // LocalPeer.realm isProcessed = consumeMessage(message); break; case PROXY: //TODO: change this its almost the same as above, make it sync, so no router code involved if (handleByAgent(message, isProcessed, message, matched)) { isProcessed = true; } break; case RELAY: // might be complicated, lets make it listener // now isProcessed = consumeMessage(message); //if its not redirected its break; case REDIRECT: //TODO: change this its almost the same as above, make it sync, so no router code involved if (handleByAgent(message, isProcessed, message, matched)) { isProcessed = true; } break; } return isProcessed; } @Override public boolean receiveMessage(IMessage message) { logger.debug("Receiving message in server."); boolean isProcessed = false; // we set the peer in the message so we can later reply directly message.setPeer(PeerImpl.this); if (message.isRequest()) { IRequest req = message; Avp destRealmAvp = req.getAvps().getAvp(Avp.DESTINATION_REALM); String destRealm = null; if (destRealmAvp == null) { // TODO: add that missing avp in "Failed-AVP" avp... sendErrorAnswer(message, "Missing Destination-Realm AVP", ResultCode.MISSING_AVP); return true; } else { try { destRealm = destRealmAvp.getDiameterIdentity(); } catch (AvpDataException ade) { sendErrorAnswer(message, "Failed to parse Destination-Realm AVP", ResultCode.INVALID_AVP_VALUE, destRealmAvp); return true; } } IRealmTable realmTable = router.getRealmTable(); if (!realmTable.realmExists(destRealm)) { // send no such realm answer. logger.warn( "Received a request for an unrecognized realm: [{}]. Answering with 3003 (DIAMETER_REALM_NOT_SERVED) Result-Code.", destRealm); sendErrorAnswer(message, null, ResultCode.REALM_NOT_SERVED); return true; } ApplicationId appId = message.getSingleApplicationId(); if (appId == null) { logger.warn("Receive a message with no Application Id. Answering with 5005 (MISSING_AVP) Result-Code."); sendErrorAnswer(message, "Missing Application-Id", ResultCode.MISSING_AVP); // TODO: add Auth-Application-Id, Acc-Application-Id and Vendor-Specific-Application-Id, can be empty return true; } // check condition for local processing. Avp destHostAvp = req.getAvps().getAvp(Avp.DESTINATION_HOST); // 6.1.4. Processing Local Requests // A request is known to be for local consumption when one of the // following conditions occur: // - The Destination-Host AVP contains the local host's identity, // - The Destination-Host AVP is not present, the Destination-Realm AVP // contains a realm the server is configured to process locally, and // the Diameter application is locally supported, or // - Both the Destination-Host and the Destination-Realm are not // present. try { isProcessed = processMessage(message); if (!isProcessed) { String destHost = (destHostAvp == null ? null : destHostAvp.getDiameterIdentity()); //NOTE: this check should be improved, it checks if there is connection to peer, otherwise we cant serve it. //possibly also match realm. IPeer p = (IPeer) peerTable.getPeer(destHost); if (p != null && p.hasValidConnection()) { isProcessed = consumeMessage(message); } else { // RFC 3588 // 6.1 // 4. If none of the above is successful, an answer is returned with the // Result-Code set to DIAMETER_UNABLE_TO_DELIVER, with the E-bit set. logger.warn( "Received message for unknown peer [{}]. Answering with 3002 (UNABLE_TO_DELIVER) Result-Code.", destHost); sendErrorAnswer(req, "No connection to peer", ResultCode.UNABLE_TO_DELIVER); isProcessed = true; } } } catch (AvpDataException ade) { logger.warn( "Received message with present but unparsable Destination-Host. Answering with 5004 (INVALID_AVP_VALUE) Result-Code."); sendErrorAnswer(message, "Failed to parse Destination-Host AVP", ResultCode.INVALID_AVP_VALUE, destHostAvp); return true; } } else { // answer, let client do its work isProcessed = super.receiveMessage(message); } return isProcessed; } /** * @param message * @param isProcessed * @param req * @param matched * @return */ private boolean handleByAgent(IMessage message, boolean isProcessed, IRequest req, IRealm matched) { if (ovrManager != null && ovrManager.isParenAppOverload(message.getSingleApplicationId())) { logger.debug("Request [{}] skipped, because server application is overloaded", message); sendErrorAnswer(message, "Overloaded", ResultCode.TOO_BUSY); return true; } else { try { router.registerRequestRouteInfo(message); IMessage answer = (IMessage) matched.getAgent().processRequest(req, matched); if (isDuplicateProtection && answer != null) { peerTable.saveToDuplicate(message.getDuplicationKey(), answer); } isProcessed = true; if (answer != null) { sendMessage(answer); } if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.SysGenResponse.name()).inc(); } } catch (Exception exc) { // TODO: check this!! logger.warn("Error during processing message by " + matched.getAgent().getClass(), exc); sendErrorAnswer(message, "Unable to process", ResultCode.UNABLE_TO_COMPLY); return true; } } if (isProcessed) { // NOTE: done to inc stat which informs on net work request consumption :) if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.NetGenRequest.name()).inc(); } } return isProcessed; } /** * @param message * @return */ private boolean consumeMessage(IMessage message) { // now its safe to call stupid client code.... logger.debug("In Server consumeMessage. Going to call parents class receiveMessage"); boolean isProcessed = super.receiveMessage(message); logger.debug("Did client PeerImpl process the message? [{}]", isProcessed); IMessage answer = null; // this will process if session exists. if (!isProcessed) { if (statistic.isEnabled()) { // Decrement what we have incremented in super.receiveMessage(message) since it wasn't processed statistic.getRecordByName(IStatisticRecord.Counters.NetGenRejectedRequest.name()).dec(); } NetworkReqListener listener = network.getListener(message); if (listener != null) { if (logger.isDebugEnabled()) { logger.debug("We have found an application that is a listener for this message. It is [{}]", listener.getClass().getName()); } if (isDuplicateProtection) { logger.debug("Checking if it's a duplicate, since duplicate protection is ENABLED."); answer = peerTable.isDuplicate(message); } if (answer != null) { logger.debug("This message was detected as being a duplicate"); answer.setProxiable(message.isProxiable()); answer.getAvps().removeAvp(Avp.PROXY_INFO); for (Avp avp : message.getAvps().getAvps(Avp.PROXY_INFO)) { answer.getAvps().addAvp(avp); } answer.setHopByHopIdentifier(message.getHopByHopIdentifier()); isProcessed = true; try { sendMessage(answer); if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.SysGenResponse.name()).inc(); } } catch (Exception e) { // TODO: check this!! logger.warn("Error during processing message by duplicate protection", e); sendErrorAnswer(message, "Unable to process", ResultCode.UNABLE_TO_COMPLY); return true; } } else { if (ovrManager != null && ovrManager.isParenAppOverload(message.getSingleApplicationId())) { logger.debug("Request [{}] skipped, because server application is overloaded", message); sendErrorAnswer(message, "Overloaded", ResultCode.TOO_BUSY); return true; } else { try { router.registerRequestRouteInfo(message); answer = (IMessage) listener.processRequest(message); if (isDuplicateProtection && answer != null) { peerTable.saveToDuplicate(message.getDuplicationKey(), answer); } isProcessed = true; if (isProcessed && answer != null) { // we use the peer from the request to reply directly answer.setPeer(message.getPeer()); sendMessage(answer); } if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.AppGenResponse.name()).inc(); } } catch (Exception exc) { // TODO: check this!! logger.warn("Error during processing message by listener", exc); sendErrorAnswer(message, "Unable to process", ResultCode.UNABLE_TO_COMPLY); return true; } } } } else { // NOTE: no listener defined for messages apps, response with "bad peer" stuff. logger.warn("Received message for unsupported Application-Id [{}]", message.getSingleApplicationId()); sendErrorAnswer(message, "Unsupported Application-Id", ResultCode.APPLICATION_UNSUPPORTED); return true; } } if (isProcessed) { // NOTE: done to inc stat which informs on net work request consumption :)... if (statistic.isEnabled()) { statistic.getRecordByName(IStatisticRecord.Counters.NetGenRequest.name()).inc(); } } return isProcessed; } @Override public String toString() { return new StringBuffer("LocalActionConext [isRestoreConnection()=").append(isRestoreConnection()) .append(", getPeerDescription()=").append(getPeerDescription()).append(", isConnected()=") .append(isConnected()).append(", LocalPeer=").append(metaData.getLocalPeer().getUri()).append(" ]") .toString(); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/RouterImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl; import org.jdiameter.api.Configuration; import org.jdiameter.api.MetaData; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.server.api.IRouter; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class RouterImpl extends org.jdiameter.client.impl.router.RouterImpl implements IRouter { public RouterImpl(IContainer container, IConcurrentFactory concurrentFactory, IRealmTable realmTable, Configuration config, MetaData metaData) { super(container, concurrentFactory, realmTable, config, metaData); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/StackImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl; import org.jdiameter.api.InternalException; import org.jdiameter.api.MetaData; import org.jdiameter.api.MutablePeerTable; import org.jdiameter.api.Network; import org.jdiameter.api.OverloadManager; import org.jdiameter.client.api.StackState; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class StackImpl extends org.jdiameter.client.impl.StackImpl implements StackImplMBean { @Override public MetaData getMetaData() { if (state == StackState.IDLE) { throw new IllegalStateException("Meta data not defined"); } return assembler.getComponentInstance(MetaDataImpl.class); } @Override public boolean isWrapperFor(Class aClass) throws InternalException { if (aClass == MutablePeerTable.class) { return true; } else if (aClass == Network.class) { return true; } else if (aClass == OverloadManager.class) { return true; } else { return super.isWrapperFor(aClass); } } @Override public T unwrap(Class aClass) throws InternalException { if (aClass == MutablePeerTable.class) { return assembler.getComponentInstance(aClass); } if (aClass == Network.class) { return assembler.getComponentInstance(aClass); } if (aClass == OverloadManager.class) { return assembler.getComponentInstance(aClass); } else { return super.unwrap(aClass); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/StackImplMBean.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface StackImplMBean extends org.jdiameter.client.impl.StackImplMBean { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/agent/AgentConfigurationImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.agent; import static org.jdiameter.client.impl.helpers.Parameters.*; import java.util.Properties; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.server.api.agent.IAgentConfiguration; /** * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class AgentConfigurationImpl implements IAgentConfiguration { private static final long serialVersionUID = 1L; protected Properties properties; /* * (non-Javadoc) * * @see org.jdiameter.server.api.agent.IAgentConfiguration#getProperties() */ @Override public Properties getProperties() { return this.properties; } /* * (non-Javadoc) * * @see org.jdiameter.server.api.agent.IAgentConfiguration#parse(java.lang.String ) */ @Override public IAgentConfiguration parse(String agentConfiguration) throws InternalException { if (agentConfiguration == null) { return null; } AgentConfigurationImpl conf = new AgentConfigurationImpl(); try { conf.properties = new Properties(); String[] split = agentConfiguration.split(";"); for (String s : split) { String[] data = s.split("="); conf.properties.put(data[0], data[1]); } } catch (Exception e) { throw new InternalException(e); } return conf; } /* * (non-Javadoc) * * @see org.jdiameter.server.api.agent.IAgentConfiguration#parse(org.jdiameter .api.Configuration) */ @Override public IAgentConfiguration parse(Configuration agentConfiguration) throws InternalException { if (agentConfiguration == null) { return null; } AgentConfigurationImpl conf = new AgentConfigurationImpl(); try { conf.properties = new Properties(); Configuration[] propConfs = agentConfiguration.getChildren(Properties.ordinal()); for (Configuration c : propConfs) { conf.properties.put(c.getStringValue(PropertyName.ordinal(), ""), c.getStringValue(PropertyValue.ordinal(), "")); } } catch (Exception e) { throw new InternalException(e); } return conf; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/agent/AgentImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.agent; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.server.api.agent.IAgent; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public abstract class AgentImpl implements IAgent { protected IContainer container; protected IRealmTable realmTable; /** * @param container * @param peerTable * @param realmTable */ public AgentImpl(IContainer container, IRealmTable realmTable) { super(); this.container = container; this.realmTable = realmTable; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/agent/ProxyAgentImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.agent; import org.jdiameter.api.Answer; import org.jdiameter.api.Request; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.controller.IRealm; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.server.api.agent.IProxy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author babass */ @SuppressWarnings("all") //3rd party lib public class ProxyAgentImpl extends AgentImpl implements IProxy { private static Logger logger = LoggerFactory.getLogger(ProxyAgentImpl.class); /** * @param container * @param realmTable */ public ProxyAgentImpl(IContainer container, IRealmTable realmTable) { super(container, realmTable); logger.info("proxy agent: created"); } /* * (non-Javadoc) * * @see * org.jdiameter.server.api.agent.IAgent#processRequest(org.jdiameter.client * .api.IRequest, org.jdiameter.client.api.controller.IRealm) */ @Override public Answer processRequest(IRequest request, IRealm matchedRealm) { logger.info("proxy agent: processRequest executed"); return null; } /* * (non-Javadoc) * * @see * org.jdiameter.api.EventListener#receivedSuccessMessage(org.jdiameter. * api.Message, org.jdiameter.api.Message) */ @Override public void receivedSuccessMessage(Request request, Answer answer) { logger.info("proxy agent: receivedSuccessMessage"); } /* * (non-Javadoc) * * @see * org.jdiameter.api.EventListener#timeoutExpired(org.jdiameter.api.Message) */ @Override public void timeoutExpired(Request request) { logger.info("proxy agent: timeoutExpired"); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/agent/RedirectAgentImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.agent; import java.io.IOException; import java.util.Properties; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.Request; import org.jdiameter.api.ResultCode; import org.jdiameter.api.RouteException; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.controller.IRealm; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.server.api.agent.IAgentConfiguration; import org.jdiameter.server.api.agent.IRedirect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class RedirectAgentImpl extends AgentImpl implements IRedirect { private static final Logger logger = LoggerFactory.getLogger(RedirectAgentImpl.class); /** * @param container * @param peerTable * @param realmTable */ public RedirectAgentImpl(IContainer container, IRealmTable realmTable) { super(container, realmTable); } public static final int RESULT_REDIRECT_INDICATION = ResultCode.REDIRECT_INDICATION; public static final int RESULT_INVALID_AVP_VALUE = ResultCode.INVALID_AVP_VALUE; /* * (non-Javadoc) * * @see org.jdiameter.server.api.agent.IAgent#processRequest(org.jdiameter.client.api.IRequest, * org.jdiameter.client.api.controller.IRealm) */ @Override public Answer processRequest(IRequest request, IRealm matchedRealm) { try { Answer ans = request.createAnswer(RESULT_REDIRECT_INDICATION); AvpSet set = ans.getAvps(); String[] destHosts = matchedRealm.getPeerNames(); for (String host : destHosts) { set.addAvp(Avp.REDIRECT_HOST, host, false); } IAgentConfiguration agentConfiguration = matchedRealm.getAgentConfiguration(); //default int rhuValue = RHU_REALM_AND_APPLICATION; if (agentConfiguration != null) { Properties p = agentConfiguration.getProperties(); try { rhuValue = Integer.parseInt(p.getProperty(RHU_PROPERTY, "" + rhuValue)); } catch (Exception e) { if (logger.isWarnEnabled()) { logger.warn("Failed to parse configuration value. ", e); } } } set.addAvp(Avp.REDIRECT_HOST_USAGE, rhuValue); ans.setError(true); super.container.sendMessage((IMessage) ans); } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Failure when trying to send Answer", e); } Answer ans = request.createAnswer(RESULT_INVALID_AVP_VALUE); // now lets do the magic. if (e instanceof AvpDataException && ((AvpDataException) e).getAvp() != null) { // lets add failed if its present AvpSet failedAvp = ans.getAvps().addGroupedAvp(Avp.FAILED_AVP); failedAvp.addAvp(((AvpDataException) e).getAvp()); } try { container.sendMessage((IMessage) ans); } catch (RouteException re) { if (logger.isDebugEnabled()) { logger.debug("Failure when trying to send failure answer", re); } } catch (AvpDataException ade) { if (logger.isDebugEnabled()) { logger.debug("Failure when trying to send failure answer", ade); } } catch (IllegalDiameterStateException idse) { if (logger.isDebugEnabled()) { logger.debug("Failure when trying to send failure answer", idse); } } catch (IOException ioe) { if (logger.isDebugEnabled()) { logger.debug("Failure when trying to send failure answer", ioe); } } } return null; } /* * (non-Javadoc) * * @see org.jdiameter.api.EventListener#receivedSuccessMessage(org.jdiameter.api.Message, org.jdiameter.api.Message) */ @Override public void receivedSuccessMessage(Request request, Answer answer) { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see org.jdiameter.api.EventListener#timeoutExpired(org.jdiameter.api.Message) */ @Override public void timeoutExpired(Request request) { // TODO Auto-generated method stub } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/acc/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.acc; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class Event implements StateEvent { enum Type { RECEIVED_EVENT_RECORD, RECEIVED_START_RECORD, RECEIVED_INTERIM_RECORD, RECEIVED_STOP_RECORD } Type type; AppEvent data; Event(Type type) { this.type = type; } Event(AccountRequest accountRequest) throws Exception { data = accountRequest; int type = accountRequest.getAccountingRecordType(); switch (type) { case 1: this.type = Type.RECEIVED_EVENT_RECORD; break; case 2: this.type = Type.RECEIVED_START_RECORD; break; case 3: this.type = Type.RECEIVED_INTERIM_RECORD; break; case 4: this.type = Type.RECEIVED_STOP_RECORD; break; default: throw new Exception("Unknown type " + type); } } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public void setData(Object o) { data = (AppEvent) o; } @Override public Object getData() { return data; } @Override public int compareTo(Object other) { return equals(other) ? 0 : -1; } @Override public int hashCode() { return super.hashCode(); } @Override public boolean equals(Object other) { return this == other; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/acc/IServerAccSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.acc; import java.io.Serializable; import org.jdiameter.common.api.app.acc.IAccSessionData; import org.jdiameter.common.api.app.acc.ServerAccSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerAccSessionData extends IAccSessionData { void setServerAccSessionState(ServerAccSessionState value); ServerAccSessionState getServerAccSessionState(); void setStateless(boolean value); boolean isStateless(); /** * Seconds value, its taken from either request or answer. Contained in Acct-Interim-Interval AVP * * @param value */ void setTsTimeout(long value); long getTsTimeout(); void setTsTimerId(Serializable value); Serializable getTsTimerId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/acc/ServerAccSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.acc; import java.io.Serializable; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.acc.ServerAccSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ServerAccSessionDataLocalImpl extends AppSessionDataLocalImpl implements IServerAccSessionData { protected ServerAccSessionState state = ServerAccSessionState.IDLE; protected boolean stateles = true; protected long tsTimeout = NON_INITIALIZED; protected Serializable tsTimerId; /** * */ public ServerAccSessionDataLocalImpl() { } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.acc.IServerAccSessionData# * setServerAccSessionState * (org.jdiameter.common.api.app.acc.ServerAccSessionState) */ @Override public void setServerAccSessionState(ServerAccSessionState value) { this.state = value; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.acc.IServerAccSessionData# * getServerAccSessionState() */ @Override public ServerAccSessionState getServerAccSessionState() { return this.state; } /* * (non-Javadoc) * * @see * org.jdiameter.server.impl.app.acc.IServerAccSessionData#setStateles(boolean * ) */ @Override public void setStateless(boolean value) { this.stateles = value; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.acc.IServerAccSessionData#isStateles() */ @Override public boolean isStateless() { return this.stateles; } /* * (non-Javadoc) * * @see * org.jdiameter.server.impl.app.acc.IServerAccSessionData#setTsTimeout( * long) */ @Override public void setTsTimeout(long value) { this.tsTimeout = value; } /* * (non-Javadoc) * * @see * org.jdiameter.server.impl.app.acc.IServerAccSessionData#getTsTimeout() */ @Override public long getTsTimeout() { return this.tsTimeout; } /* * (non-Javadoc) * * @see * org.jdiameter.server.impl.app.acc.IServerAccSessionData#setTsTimerId( * java.io.Serializable) */ @Override public void setTsTimerId(Serializable value) { this.tsTimerId = value; } /* * (non-Javadoc) * * @see * org.jdiameter.server.impl.app.acc.IServerAccSessionData#getTsTimerId() */ @Override public Serializable getTsTimerId() { return this.tsTimerId; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/acc/ServerAccSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.acc; import static org.jdiameter.common.api.app.acc.ServerAccSessionState.IDLE; import static org.jdiameter.common.api.app.acc.ServerAccSessionState.OPEN; import java.io.Serializable; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.ResultCode; import org.jdiameter.api.RouteException; import org.jdiameter.api.acc.ServerAccSession; import org.jdiameter.api.acc.ServerAccSessionListener; import org.jdiameter.api.acc.events.AccountAnswer; import org.jdiameter.api.acc.events.AccountRequest; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.acc.IServerAccActionContext; import org.jdiameter.common.api.app.acc.ServerAccSessionState; import org.jdiameter.common.impl.app.acc.AppAccSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Server Accounting session implementation * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ServerAccSessionImpl extends AppAccSessionImpl implements EventListener, ServerAccSession, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(ServerAccSessionImpl.class); // Factories and Listeners -------------------------------------------------- protected transient IServerAccActionContext context; protected transient ServerAccSessionListener listener; // Ts Timer ----------------------------------------------------------------- protected static final String TIMER_NAME_TS = "TS"; protected IServerAccSessionData sessionData; // Constructors ------------------------------------------------------------- public ServerAccSessionImpl(IServerAccSessionData sessionData, ISessionFactory sessionFactory, ServerAccSessionListener serverSessionListener, IServerAccActionContext serverContextListener, StateChangeListener stLst, boolean stateless) { // TODO Auto-generated constructor stub this(sessionData, sessionFactory, serverSessionListener, serverContextListener, stLst); this.sessionData.setTsTimeout(0); // 0 == turn off this.sessionData.setStateless(stateless); } public ServerAccSessionImpl(IServerAccSessionData sessionData, ISessionFactory sessionFactory, ServerAccSessionListener serverSessionListener, IServerAccActionContext serverContextListener, StateChangeListener stLst) { // TODO Auto-generated constructor stub super(sessionFactory, sessionData); this.sessionData = sessionData; this.listener = serverSessionListener; this.context = serverContextListener; super.addStateChangeNotification(stLst); } @Override public void sendAccountAnswer(AccountAnswer accountAnswer) throws InternalException, IllegalStateException, RouteException, OverloadException { try { AvpSet avpSet = accountAnswer.getMessage().getAvps(); Avp acctInterimIntervalAvp = avpSet.getAvp(Avp.ACCT_INTERIM_INTERVAL); //Unsigned32 if (acctInterimIntervalAvp != null) { try { this.sessionData.setTsTimeout(acctInterimIntervalAvp.getUnsigned32()); } catch (AvpDataException e) { throw new InternalException(e); } } cancelTsTimer(); startTsTimer(); session.send(accountAnswer.getMessage()); /* TODO: Do we need to notify state change ? */ if (isStateless() && isValid()) { session.release(); } } catch (IllegalDiameterStateException e) { throw new IllegalStateException(e); } } @Override public boolean isStateless() { return sessionData.isStateless(); } @SuppressWarnings("unchecked") protected void setState(IAppSessionState newState) { IAppSessionState oldState = sessionData.getServerAccSessionState(); sessionData.setServerAccSessionState((ServerAccSessionState) newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return sessionData.isStateless() ? handleEventForStatelessMode(event) : handleEventForStatefulMode(event); } public boolean handleEventForStatelessMode(StateEvent event) throws InternalException, OverloadException { try { //NOTE: NO Ts Timer here //this will handle RTRs as well, no need to alter. ServerAccSessionState state = sessionData.getServerAccSessionState(); switch (state) { case IDLE: { switch ((Event.Type) event.getType()) { case RECEIVED_START_RECORD: // Current State: IDLE // Event: Accounting start request received, and successfully processed. // Action: Send accounting start answer // New State: IDLE if (listener != null) { try { listener.doAccRequestEvent(this, (AccountRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } // TODO: This is unnecessary state change: setState(IDLE); break; case RECEIVED_EVENT_RECORD: // Current State: IDLE // Event: Accounting event request received, and successfully processed. // Action: Send accounting event answer // New State: IDLE if (listener != null) { try { listener.doAccRequestEvent(this, (AccountRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } // FIXME: it is required, so we know it ends up again in IDLE! setState(IDLE); break; case RECEIVED_INTERIM_RECORD: // Current State: IDLE // Event: Interim record received, and successfully processed. // Action: Send accounting interim answer // New State: IDLE if (listener != null) { try { listener.doAccRequestEvent(this, (AccountRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } // TODO: This is unnecessary state change: setState(IDLE); break; case RECEIVED_STOP_RECORD: // Current State: IDLE // Event: Accounting stop request received, and successfully processed // Action: Send accounting stop answer // New State: IDLE if (listener != null) { try { listener.doAccRequestEvent(this, (AccountRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } // TODO: This is unnecessary state change: setState(IDLE); break; default: throw new IllegalStateException("Current state " + state + " action " + event.getType()); } } } } catch (Exception e) { logger.debug("Can not process event", e); return false; } finally { // TODO: Since setState was removed, we are now using this to terminate. Correct? // We can't release here, answer needs to be sent through. done at send. // release(); } return true; } public boolean handleEventForStatefulMode(StateEvent event) throws InternalException, OverloadException { try { if (((AccountRequest) event.getData()).getMessage().isReTransmitted()) { try { cancelTsTimer(); startTsTimer(); setState(OPEN); listener.doAccRequestEvent(this, (AccountRequest) event.getData()); if (context != null) { context.sessionTimerStarted(this, null); } } catch (Exception e) { logger.debug("Can not handle event", e); setState(IDLE); } return true; } else { ServerAccSessionState state = sessionData.getServerAccSessionState(); AccountRequest request = (AccountRequest) event.getData(); AvpSet avpSet = request.getMessage().getAvps(); Avp acctInterimIntervalAvp = avpSet.getAvp(85);//Unsigned32 if (acctInterimIntervalAvp != null) { this.sessionData.setTsTimeout(acctInterimIntervalAvp.getUnsigned32()); } switch (state) { case IDLE: { switch ((Event.Type) event.getType()) { case RECEIVED_START_RECORD: // Current State: IDLE // Event: Accounting start request received, and successfully processed. // Action: Send accounting start answer, Start Ts // New State: OPEN setState(OPEN); if (listener != null) { try { listener.doAccRequestEvent(this, (AccountRequest) event.getData()); cancelTsTimer(); startTsTimer(); if (context != null) { context.sessionTimerStarted(this, null); } } catch (Exception e) { logger.debug("Can not handle event", e); setState(IDLE); } } break; case RECEIVED_EVENT_RECORD: // Current State: IDLE // Event: Accounting event request received, and // successfully processed. // Action: Send accounting event answer // New State: IDLE if (listener != null) { try { listener.doAccRequestEvent(this, (AccountRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } break; } break; } case OPEN: { switch ((Event.Type) event.getType()) { case RECEIVED_INTERIM_RECORD: // Current State: OPEN // Event: Interim record received, and successfully // processed. // Action: Send accounting interim answer, Restart Ts // New State: OPEN try { listener.doAccRequestEvent(this, (AccountRequest) event.getData()); cancelTsTimer(); startTsTimer(); if (context != null) { context.sessionTimerStarted(this, null); } } catch (Exception e) { logger.debug("Can not handle event", e); setState(IDLE); } break; case RECEIVED_STOP_RECORD: // Current State: OPEN // Event: Accounting stop request received, and // successfully // processed // Action: Send accounting stop answer, Stop Ts // New State: IDLE try { setState(IDLE); cancelTsTimer(); listener.doAccRequestEvent(this, (AccountRequest) event.getData()); if (context != null) { context.sessionTimerCanceled(this, null); } } catch (Exception e) { logger.debug("Can not handle event", e); setState(IDLE); } break; } break; } } } } catch (Exception e) { logger.debug("Can not process event", e); return false; } return true; } private void startTsTimer() { try { sendAndStateLock.lock(); if (sessionData.getTsTimeout() > 0) { Serializable tsTid = super.timerFacility.schedule(sessionData.getSessionId(), TIMER_NAME_TS, sessionData.getTsTimeout()); sessionData.setTsTimerId(tsTid); } return; } finally { sendAndStateLock.unlock(); } } private void cancelTsTimer() { try { sendAndStateLock.lock(); Serializable tsTid = sessionData.getTsTimerId(); if (tsTid != null) { super.timerFacility.cancel(tsTid); sessionData.setTsTimerId(null); } } finally { sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TIMER_NAME_TS)) { if (context != null) { try { context.sessionTimeoutElapses(ServerAccSessionImpl.this); } catch (InternalException e) { logger.debug("Failure on processing expired Ts", e); } } setState(IDLE); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } protected Answer createStopAnswer(Request request) { Answer answer = request.createAnswer(ResultCode.SUCCESS); answer.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 4); answer.getAvps().addAvp(request.getAvps().getAvp(Avp.ACC_RECORD_NUMBER)); return answer; } protected Answer createInterimAnswer(Request request) { Answer answer = request.createAnswer(ResultCode.SUCCESS); answer.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 3); answer.getAvps().addAvp(request.getAvps().getAvp(Avp.ACC_RECORD_NUMBER)); return answer; } protected Answer createEventAnswer(Request request) { Answer answer = request.createAnswer(ResultCode.SUCCESS); answer.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 2); answer.getAvps().addAvp(request.getAvps().getAvp(Avp.ACC_RECORD_NUMBER)); return answer; } protected Answer createStartAnswer(Request request) { Answer answer = request.createAnswer(ResultCode.SUCCESS); answer.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 1); answer.getAvps().addAvp(request.getAvps().getAvp(Avp.ACC_RECORD_NUMBER)); return answer; } @Override @SuppressWarnings("unchecked") public E getState(Class eClass) { return eClass == ServerAccSessionState.class ? (E) sessionData.getServerAccSessionState() : null; } @Override public Answer processRequest(Request request) { if (request.getCommandCode() == AccountRequest.code) { try { sendAndStateLock.lock(); handleEvent(new Event(createAccountRequest(request))); } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } } else { try { listener.doOtherEvent(this, createAccountRequest(request), null); } catch (Exception e) { logger.debug("Can not handle event", e); } } return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { if (request.getCommandCode() == AccountRequest.code) { try { sendAndStateLock.lock(); handleEvent(new Event(createAccountRequest(request))); } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } try { listener.doAccRequestEvent(this, createAccountRequest(request)); } catch (Exception e) { logger.debug("Can not handle event", e); } } else { try { listener.doOtherEvent(this, createAccountRequest(request), createAccountAnswer(answer)); } catch (Exception e) { logger.debug("Can not handle event", e); } } } @Override public void timeoutExpired(Request request) { // FIXME: alexandre: We don't do anything here... are we even getting this on server? } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/auth/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.auth; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class Event implements StateEvent { enum Type { RECEIVE_AUTH_REQUEST, RECEIVE_STR_REQUEST, SEND_ASR_REQUEST, SEND_ASR_FAILURE, RECEIVE_ASR_ANSWER, TIMEOUT_EXPIRES } Type type; AppEvent data; Event(Type type, AppEvent data) { this.type = type; this.data = data; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public void setData(Object o) { data = (AppEvent) o; } @Override public Object getData() { return data; } @Override public int compareTo(Object o) { return 0; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/auth/IServerAuthSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.auth; import java.io.Serializable; import org.jdiameter.common.api.app.auth.IAuthSessionData; import org.jdiameter.common.api.app.auth.ServerAuthSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerAuthSessionData extends IAuthSessionData { ServerAuthSessionState getServerAuthSessionState(); void setServerAuthSessionState(ServerAuthSessionState state); boolean isStateless(); void setStateless(boolean b); void setTsTimeout(long l); long getTsTimeout(); void setTsTimerId(Serializable tid); Serializable getTsTimerId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/auth/ServerAuthSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.auth; import java.io.Serializable; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.auth.ServerAuthSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ServerAuthSessionDataLocalImpl extends AppSessionDataLocalImpl implements IServerAuthSessionData { protected ServerAuthSessionState state = ServerAuthSessionState.IDLE; protected Serializable tsTimerId; protected long tsTimeout = NON_INITIALIZED; protected boolean stateless = true; /** * */ public ServerAuthSessionDataLocalImpl() { } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.auth.IServerAuthSessionData#getServerAuthSessionState() */ @Override public ServerAuthSessionState getServerAuthSessionState() { return this.state; } /* * (non-Javadoc) * * @see * org.jdiameter.server.impl.app.auth.IServerAuthSessionData#setServerAuthSessionState(org.jdiameter.common.api.app.auth. * ServerAuthSessionState) */ @Override public void setServerAuthSessionState(ServerAuthSessionState state) { this.state = state; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.auth.IServerAuthSessionData#isStateless() */ @Override public boolean isStateless() { return this.stateless; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.auth.IServerAuthSessionData#setStateless(boolean) */ @Override public void setStateless(boolean stateless) { this.stateless = stateless; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.auth.IServerAuthSessionData#setTsTimeout(long) */ @Override public void setTsTimeout(long tsTimeout) { this.tsTimeout = tsTimeout; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.auth.IServerAuthSessionData#getTsTimeout() */ @Override public long getTsTimeout() { return this.tsTimeout; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.auth.IServerAuthSessionData#setTsTimerId(java.io.Serializable) */ @Override public void setTsTimerId(Serializable tsTimerId) { this.tsTimerId = tsTimerId; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.auth.IServerAuthSessionData#getTsTimerId() */ @Override public Serializable getTsTimerId() { return this.tsTimerId; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/auth/ServerAuthSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.auth; import static org.jdiameter.common.api.app.auth.ServerAuthSessionState.*; import static org.jdiameter.server.impl.app.auth.Event.Type.*; import java.io.Serializable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.auth.ServerAuthSession; import org.jdiameter.api.auth.ServerAuthSessionListener; import org.jdiameter.api.auth.events.AbortSessionAnswer; import org.jdiameter.api.auth.events.AbortSessionRequest; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.auth.events.SessionTermAnswer; import org.jdiameter.api.auth.events.SessionTermRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.auth.IAuthMessageFactory; import org.jdiameter.common.api.app.auth.IServerAuthActionContext; import org.jdiameter.common.api.app.auth.ServerAuthSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.auth.AbortSessionAnswerImpl; import org.jdiameter.common.impl.app.auth.AbortSessionRequestImpl; import org.jdiameter.common.impl.app.auth.AppAuthSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Server Authorization session implementation * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ServerAuthSessionImpl extends AppAuthSessionImpl implements ServerAuthSession, EventListener, NetworkReqListener { private static final long serialVersionUID = 1L; protected static final Logger logger = LoggerFactory.getLogger(ServerAuthSessionImpl.class); protected IServerAuthSessionData sessionData; // Session State Handling --------------------------------------------------- private Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IAuthMessageFactory factory; protected transient IServerAuthActionContext context; protected transient ServerAuthSessionListener listener; // Ts Timer ----------------------------------------------------------------- protected static final String TIMER_NAME_TS = "AUTH_TS"; // Constructors ------------------------------------------------------------- public ServerAuthSessionImpl(IServerAuthSessionData sessionData, ISessionFactory sf, ServerAuthSessionListener lst, IAuthMessageFactory fct, StateChangeListener scListener, IServerAuthActionContext context, long tsTimeout, boolean stateless) { super(sf, sessionData); super.appId = fct.getApplicationId(); this.listener = lst; this.factory = fct; this.context = context; this.sessionData = sessionData; this.sessionData.setStateless(stateless); this.sessionData.setTsTimeout(tsTimeout); super.addStateChangeNotification(scListener); } // ServerAuthSession Implementation methods --------------------------------- @Override public void sendAuthAnswer(AppAnswerEvent appAnswerEvent) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(null, appAnswerEvent); } @Override public void sendReAuthRequest(ReAuthRequest reAuthRequest) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(null, reAuthRequest); } @Override public void sendAbortSessionRequest(AbortSessionRequest abortSessionRequest) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_ASR_REQUEST, abortSessionRequest); } @Override public void sendSessionTerminationAnswer(SessionTermAnswer sessionTermAnswer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(null, sessionTermAnswer); } protected void send(Event.Type type, AppEvent event) throws InternalException { try { sendAndStateLock.lock(); if (type != null) { handleEvent(new Event(type, event)); } session.send(event.getMessage(), this); } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } @Override public boolean isStateless() { return sessionData.isStateless(); } @SuppressWarnings("unchecked") protected void setState(ServerAuthSessionState newState) { IAppSessionState oldState = sessionData.getServerAuthSessionState(); sessionData.setServerAuthSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } } @Override @SuppressWarnings("unchecked") public E getState(Class eClass) { return eClass == ServerAuthSessionState.class ? (E) sessionData.getServerAuthSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return isStateless() ? handleEventForStatelessSession(event) : handleEventForStatefullSession(event); } public boolean handleEventForStatelessSession(StateEvent event) throws InternalException, OverloadException { try { switch (sessionData.getServerAuthSessionState()) { case IDLE: switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_REQUEST: // Current State: IDLE // Event: Service-specific authorization request received, and successfully processed // Action: Send service specific answer // New State: IDLE setState(IDLE); listener.doAuthRequestEvent(this, (AppRequestEvent) event.getData()); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } } catch (Throwable t) { throw new InternalException(t); } return true; } public boolean handleEventForStatefullSession(StateEvent event) throws InternalException, OverloadException { ServerAuthSessionState state = sessionData.getServerAuthSessionState(); ServerAuthSessionState oldState = state; try { switch (state) { case IDLE: { switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_REQUEST: try { // Current State: IDLE // Event: Service-specific authorization request received, and user is authorized // Action: Send successful service specific answer // New State: OPEN setState(OPEN); listener.doAuthRequestEvent(this, (AppRequestEvent) event.getData()); } catch (Exception e) { setState(IDLE); } break; case RECEIVE_STR_REQUEST: try { // Current State: ANY // Event: STR Received // Action: Send STA, Cleanup // New State: IDLE setState(IDLE); listener.doSessionTerminationRequestEvent(this, (SessionTermRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } break; case SEND_ASR_REQUEST: setState(DISCONNECTED); break; case TIMEOUT_EXPIRES: if (context != null) { context.accessTimeoutElapses(this); } setState(IDLE); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } case OPEN: { switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_REQUEST: try { // Current State: OPEN // Event: Service-specific authorization request received, and user is authorized // Action: Send successful service specific answer // New State: OPEN listener.doAuthRequestEvent(this, (AppRequestEvent) event.getData()); } catch (Exception e) { // Current State: OPEN // Event: Service-specific authorization request received, and user is not authorized // Action: Send failed service specific answer, Cleanup // New State: IDLE setState(IDLE); } break; case RECEIVE_STR_REQUEST: try { setState(IDLE); listener.doSessionTerminationRequestEvent(this, (SessionTermRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } break; case SEND_ASR_REQUEST: // Current State: OPEN // Event: Home server wants to terminate the service // Action: Send ASR // New State: DISCON setState(DISCONNECTED); break; case TIMEOUT_EXPIRES: // Current State: OPEN // Event: Authorization-Lifetime (and Auth-Grace-Period) expires on home server. // Action: Cleanup // New State: IDLE // Current State: OPEN // Event: Session-Timeout expires on home server // Action: Cleanup // New State: IDLE if (context != null) { context.accessTimeoutElapses(this); } setState(IDLE); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } case DISCONNECTED: { switch ((Event.Type) event.getType()) { case SEND_ASR_FAILURE: // Current State: DISCON // Event: Failure to send ASR // Action: Wait, Re-send ASR // New State: DISCON setState(DISCONNECTED); break; case RECEIVE_ASR_ANSWER: // Current State: DISCON // Event: ASR successfully sent and ASA Received with Result-Code // Action: Cleanup // New State: IDLE setState(IDLE); listener.doAbortSessionAnswerEvent(this, (AbortSessionAnswer) event.getData()); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } default: { logger.debug("Unknown state {}", state); break; } } // post processing if (oldState != state) { if (OPEN.equals(state) && context != null) { if (context != null) { cancelTsTimer(); startTsTimer(); } // scheduler.schedule(new Runnable() { // public void run() { // if (context != null) { // try { // handleEvent(new Event(TIMEOUT_EXPIRES, null)); // } // catch (Exception e) { // logger.debug("Can not handle event", e); // } // } // } // }, context.createAccessTimer(), TimeUnit.MILLISECONDS); } } } catch (Throwable t) { throw new InternalException(t); } return true; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } @Override public void timeoutExpired(Request request) { try { if (request.getCommandCode() == AbortSessionRequest.code) { handleEvent(new Event(Event.Type.SEND_ASR_FAILURE, new AbortSessionRequestImpl(request))); } else { logger.debug("Timeout for unknown request {}", request); } } catch (Exception e) { logger.debug("Can not handle event", e); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } protected void startTsTimer() { try { sendAndStateLock.lock(); if (sessionData.getTsTimeout() > 0) { sessionData.setTsTimerId( super.timerFacility.schedule(sessionData.getSessionId(), TIMER_NAME_TS, sessionData.getTsTimeout())); } } finally { sendAndStateLock.unlock(); } } protected void cancelTsTimer() { try { sendAndStateLock.lock(); Serializable tsTimerId = sessionData.getTsTimerId(); if (tsTimerId != null) { super.timerFacility.cancel(tsTimerId); sessionData.setTsTimerId(null); } } finally { sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TIMER_NAME_TS)) { try { sendAndStateLock.lock(); sessionData.setTsTimerId(null); handleEvent(new Event(TIMEOUT_EXPIRES, null)); } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } ServerAuthSessionImpl other = (ServerAuthSessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); this.context = null; this.listener = null; } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ServerAuthSession session; Request request; @Override public void run() { if (request != null) { if (request.getCommandCode() == factory.getAuthMessageCommandCode()) { try { sendAndStateLock.lock(); handleEvent(new Event(RECEIVE_AUTH_REQUEST, factory.createAuthRequest(request))); } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } } else { try { listener.doOtherEvent(session, factory.createAuthRequest(request), null); } catch (Exception e) { logger.debug("Can not handle event", e); } } } } } private class AnswerDelivery implements Runnable { ServerAuthSession session; Answer answer; Request request; @Override public void run() { try { sendAndStateLock.lock(); if (request.getCommandCode() == factory.getAuthMessageCommandCode()) { handleEvent(new Event(RECEIVE_AUTH_REQUEST, factory.createAuthRequest(request))); } else if (request.getCommandCode() == AbortSessionRequest.code) { handleEvent(new Event(RECEIVE_ASR_ANSWER, new AbortSessionAnswerImpl(answer))); } else { listener.doOtherEvent(session, factory.createAuthRequest(request), new AppAnswerEventImpl(answer)); } } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cca/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.cca; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { public enum Type { RECEIVED_EVENT, SENT_EVENT_RESPONSE, RECEIVED_INITIAL, SENT_INITIAL_RESPONSE, RECEIVED_UPDATE, SENT_UPDATE_RESPONSE, RECEIVED_TERMINATE, SENT_TERMINATE_RESPONSE, // These have no transition, no state resources, timers SENT_RAR, RECEIVED_RAA; } Type type; AppRequestEvent request; AppAnswerEvent answer; Event(Type type) { this.type = type; } Event(Type type, AppRequestEvent request, AppAnswerEvent answer) { this.type = type; this.answer = answer; this.request = request; } Event(boolean isRequest, JCreditControlRequest request, JCreditControlAnswer answer) { this.answer = answer; this.request = request; /** *
               * 8.3.  CC-Request-Type AVP
               *
               *     The CC-Request-Type AVP (AVP Code 416) is of type Enumerated and
               *     contains the reason for sending the credit-control request message.
               *     It MUST be present in all Credit-Control-Request messages.  The
               *     following values are defined for the CC-Request-Type AVP:
               *
               *     INITIAL_REQUEST                 1
               *     UPDATE_REQUEST                  2
               *     TERMINATION_REQUEST             3
               *     EVENT_REQUEST                   4
               * 
      */ if (isRequest) { switch (request.getRequestTypeAVPValue()) { case 1: type = Type.RECEIVED_INITIAL; break; case 2: type = Type.RECEIVED_UPDATE; break; case 3: type = Type.RECEIVED_TERMINATE; break; case 4: type = Type.RECEIVED_EVENT; break; default: throw new IllegalArgumentException("Invalid value or Request-Type AVP not present in CC Request."); } } else { switch (answer.getRequestTypeAVPValue()) { case 1: type = Type.SENT_INITIAL_RESPONSE; break; case 2: type = Type.SENT_UPDATE_RESPONSE; break; case 3: type = Type.SENT_TERMINATE_RESPONSE; break; case 4: type = Type.SENT_EVENT_RESPONSE; break; default: throw new IllegalArgumentException("Invalid value or Request-Type AVP not present in CC Answer."); } } } @Override public E encodeType(Class eClass) { return eClass == Event.Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return this.request != null ? this.request : this.answer; } @Override public void setData(Object data) { // data = (AppEvent) o; // FIXME: What should we do here?! Is it request or answer? } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cca/IServerCCASessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.cca; import java.io.Serializable; import org.jdiameter.common.api.app.cca.ICCASessionData; import org.jdiameter.common.api.app.cca.ServerCCASessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerCCASessionData extends ICCASessionData { boolean isStateless(); void setStateless(boolean stateless); ServerCCASessionState getServerCCASessionState(); void setServerCCASessionState(ServerCCASessionState state); void setTccTimerId(Serializable tccTimerId); Serializable getTccTimerId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cca/ServerCCASessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.cca; import java.io.Serializable; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.cca.ServerCCASessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ServerCCASessionDataLocalImpl extends AppSessionDataLocalImpl implements IServerCCASessionData { protected boolean stateless = true; protected ServerCCASessionState state = ServerCCASessionState.IDLE; protected Serializable tccTimerId; /** * */ public ServerCCASessionDataLocalImpl() { } @Override public boolean isStateless() { return stateless; } @Override public void setStateless(boolean stateless) { this.stateless = stateless; } @Override public ServerCCASessionState getServerCCASessionState() { return state; } @Override public void setServerCCASessionState(ServerCCASessionState state) { this.state = state; } @Override public Serializable getTccTimerId() { return tccTimerId; } @Override public void setTccTimerId(Serializable tccTimerId) { this.tccTimerId = tccTimerId; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cca/ServerCCASessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.cca; import org.jdiameter.api.*; import org.jdiameter.api.app.*; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.cca.ServerCCASession; import org.jdiameter.api.cca.ServerCCASessionListener; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.cca.ICCAMessageFactory; import org.jdiameter.common.api.app.cca.IServerCCASessionContext; import org.jdiameter.common.api.app.cca.ServerCCASessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.auth.ReAuthAnswerImpl; import org.jdiameter.common.impl.app.auth.ReAuthRequestImpl; import org.jdiameter.common.impl.app.cca.AppCCASessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import static org.jdiameter.common.api.app.cca.ServerCCASessionState.IDLE; import static org.jdiameter.common.api.app.cca.ServerCCASessionState.OPEN; /** * Credit Control Application Server session implementation * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ServerCCASessionImpl extends AppCCASessionImpl implements ServerCCASession, NetworkReqListener, EventListener { private static final Logger logger = LoggerFactory.getLogger(ServerCCASessionImpl.class); protected IServerCCASessionData sessionData; // Session State Handling --------------------------------------------------- protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient ICCAMessageFactory factory = null; protected transient IServerCCASessionContext context = null; protected transient ServerCCASessionListener listener = null; protected static final String TCC_TIMER_NAME = "TCC_CCASERVER_TIMER"; protected long[] authAppIds = new long[]{4}; //protected String originHost, originRealm; public ServerCCASessionImpl(IServerCCASessionData data, ICCAMessageFactory fct, ISessionFactory sf, ServerCCASessionListener lst, IServerCCASessionContext ctx, StateChangeListener stLst) { super(sf, data); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (data == null) { throw new IllegalArgumentException("IServerCCASessionData can not be null"); } if (fct.getApplicationIds() == null) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } sessionData = data; context = ctx; authAppIds = fct.getApplicationIds(); listener = lst; factory = fct; super.addStateChangeNotification(stLst); } @Override public void sendCreditControlAnswer(JCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { handleEvent(new Event(false, null, answer)); } @Override public void sendReAuthRequest(ReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SENT_RAR, request, null); } @Override public boolean isStateless() { return sessionData.isStateless(); } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == ServerCCASessionState.class ? (E) sessionData.getServerCCASessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { ServerCCASessionState newState = null; try { sendAndStateLock.lock(); ServerCCASessionState state = this.sessionData.getServerCCASessionState(); // Can be null if there is no state transition, transition to IDLE state should terminate this app session Event localEvent = (Event) event; //Its kind of awkward, but with two state on server side its easier to go through event types? //but for sake of FSM readability Event.Type eventType = (Event.Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVED_INITIAL: listener.doCreditControlRequest(this, (JCreditControlRequest) localEvent.getRequest()); break; case RECEIVED_EVENT: // Current State: IDLE // Event: CC event request received and successfully processed // Action: Send CC event answer // New State: IDLE listener.doCreditControlRequest(this, (JCreditControlRequest) localEvent.getRequest()); break; case SENT_EVENT_RESPONSE: // Current State: IDLE // Event: CC event request received and successfully processed // Action: Send CC event answer // New State: IDLE // Current State: IDLE // Event: CC event request received but not successfully processed // Action: Send CC event answer with Result-Code != SUCCESS // New State: IDLE newState = IDLE; dispatchEvent(localEvent.getAnswer()); setState(newState); break; case SENT_INITIAL_RESPONSE: JCreditControlAnswer answer = (JCreditControlAnswer) localEvent.getAnswer(); try { long resultCode = answer.getResultCodeAvp().getUnsigned32(); // Current State: IDLE // Event: CC initial request received and successfully processed // Action: Send CC initial answer, reserve units, start Tcc // New State: OPEN if (isSuccess(resultCode)) { startTcc(answer.getValidityTimeAvp()); newState = OPEN; } // Current State: IDLE // Event: CC initial request received but not successfully processed // Action: Send CC initial answer with Result-Code != SUCCESS // New State: IDLE else { newState = OPEN; } dispatchEvent(localEvent.getAnswer()); setState(newState); } catch (AvpDataException e) { throw new InternalException(e); } break; case RECEIVED_UPDATE: case RECEIVED_TERMINATE: Answer errorAnswer = ((Request) localEvent.getRequest().getMessage()) .createAnswer(ResultCode.UNKNOWN_SESSION_ID); session.send(errorAnswer); logger.debug( "Received an UPDATE or TERMINATE for a new session. Answering with 5002 (UNKNOWN_SESSION_ID) and terminating session."); // and let it throw exception anyway ... default: throw new InternalException("Wrong state: " + IDLE + " on event: " + eventType + " " + localEvent.getRequest() + " " + localEvent.getAnswer()); } case OPEN: switch (eventType) { /* * This should not happen, it should be silently discarded, right? * case RECEIVED_INITIAL: * // only for rtr * if (((JCreditControlRequest) localEvent.getRequest()).getMessage().isReTransmitted()) { * listener.doCreditControlRequest(this, (JCreditControlRequest) localEvent.getRequest()); * } * else { * //do nothing? * } * break; */ case RECEIVED_UPDATE: listener.doCreditControlRequest(this, (JCreditControlRequest) localEvent.getRequest()); break; case SENT_UPDATE_RESPONSE: JCreditControlAnswer answer = (JCreditControlAnswer) localEvent.getAnswer(); startTcc(answer.getValidityTimeAvp()); dispatchEvent(localEvent.getAnswer()); break; case RECEIVED_TERMINATE: listener.doCreditControlRequest(this, (JCreditControlRequest) localEvent.getRequest()); break; case SENT_TERMINATE_RESPONSE: answer = (JCreditControlAnswer) localEvent.getAnswer(); try { // Current State: OPEN // Event: CC termination request received and successfully processed // Action: Send CC termination answer, Stop Tcc, debit used units // New State: IDLE if (isSuccess(answer.getResultCodeAvp().getUnsigned32())) { stopTcc(false); } else { // Current State: OPEN // Event: CC termination request received but not successfully processed // Action: Send CC termination answer with Result-Code != SUCCESS, debit used units // New State: IDLE // It's a failure, we wait for Tcc to fire -- FIXME: Alexandre: Should we? } } catch (AvpDataException e) { throw new InternalException(e); } newState = IDLE; dispatchEvent(localEvent.getAnswer()); setState(newState); break; case RECEIVED_RAA: listener.doReAuthAnswer(this, new ReAuthRequestImpl(localEvent.getRequest().getMessage()), new ReAuthAnswerImpl((Answer) localEvent.getAnswer().getMessage())); break; case SENT_RAR: dispatchEvent(localEvent.getRequest()); break; } } return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } private class TccScheduledTask implements Runnable { ServerCCASession session = null; private TccScheduledTask(ServerCCASession session) { super(); this.session = session; } @Override public void run() { // Current State: OPEN // Event: Session supervision timer Tcc expired // Action: Release reserved units // New State: IDLE context.sessionSupervisionTimerExpired(session); try { sendAndStateLock.lock(); // tccFuture = null; sessionData.setTccTimerId(null); setState(IDLE); } finally { sendAndStateLock.unlock(); } } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); //rd.session = (ServerCCASession) LocalDataSource.INSTANCE.getSession(request.getSessionId()); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } @Override public void timeoutExpired(Request request) { context.timeoutExpired(request); //FIXME: Should we release ? } private void startTcc(Avp validityAvp) { long tccTimeout; if (validityAvp != null) { try { tccTimeout = 2 * validityAvp.getUnsigned32(); } catch (AvpDataException e) { logger.debug("Unable to retrieve Validity-Time AVP value, using default.", e); tccTimeout = 2 * context.getDefaultValidityTime(); } } else { logger.debug("No Validity-Time AVP found, using default validity time {}.", context.getDefaultValidityTime()); tccTimeout = 2 * context.getDefaultValidityTime(); } if (sessionData.getTccTimerId() != null) { stopTcc(true); //tccFuture = super.scheduler.schedule(new TccScheduledTask(this), defaultValue, TimeUnit.SECONDS); this.sessionData .setTccTimerId(super.timerFacility.schedule(this.getSessionId(), TCC_TIMER_NAME, tccTimeout * 1000)); // FIXME: this accepts Future! context.sessionSupervisionTimerReStarted(this, null); } else { //tccFuture = super.scheduler.schedule(new TccScheduledTask(this), defaultValue, TimeUnit.SECONDS); this.sessionData .setTccTimerId(super.timerFacility.schedule(this.getSessionId(), TCC_TIMER_NAME, tccTimeout * 1000)); //FIXME: this accepts Future! context.sessionSupervisionTimerStarted(this, null); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(TCC_TIMER_NAME)) { logger.debug("Received onTimer for TCC timer, session ID '{}'", getSessionId()); new TccScheduledTask(this).run(); } } private void stopTcc(boolean willRestart) { Serializable tccTimerId = this.sessionData.getTccTimerId(); if (tccTimerId != null) { // tccFuture.cancel(false); super.timerFacility.cancel(tccTimerId); // ScheduledFuture f = tccFuture; this.sessionData.setTccTimerId(null); if (!willRestart) { context.sessionSupervisionTimerStopped(this, null); } } } protected boolean isProvisional(long resultCode) { return resultCode >= 1000 && resultCode < 2000; } protected boolean isSuccess(long resultCode) { return resultCode >= 2000 && resultCode < 3000; } protected void setState(ServerCCASessionState newState) { setState(newState, true); } @SuppressWarnings("unchecked") protected void setState(ServerCCASessionState newState, boolean release) { IAppSessionState oldState = this.sessionData.getServerCCASessionState(); this.sessionData.setServerCCASessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == IDLE) { // do EVERYTHING before this! stopTcc(false); if (release) { this.release(); } } } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); this.stopTcc(false); super.release(); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void send(Event.Type type, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } protected void dispatchEvent(AppEvent event) throws InternalException { try { session.send(event.getMessage(), this); // Store last destination information // FIXME: add differentiation on server/client request //originRealm = event.getMessage().getAvps().getAvp(Avp.ORIGIN_REALM).getOctetString(); //originHost = event.getMessage().getAvps().getAvp(Avp.ORIGIN_HOST).getOctetString(); } catch (Exception e) { //throw new InternalException(e); logger.debug("Failure trying to dispatch event", e); } } private class RequestDelivery implements Runnable { ServerCCASession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case JCreditControlAnswer.code: handleEvent(new Event(true, factory.createCreditControlRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerCCASession session; Answer answer; Request request; @Override public void run() { try { // FIXME: baranowb: add message validation here!!! // We handle CCR, STR, ACR, ASR other go into extension switch (request.getCommandCode()) { case ReAuthRequest.code: handleEvent(new Event(Event.Type.RECEIVED_RAA, factory.createReAuthRequest(request), factory.createReAuthAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ServerCCASessionImpl other = (ServerCCASessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } @Override public String toString() { return "ServerCCASessionImpl [sessionData=" + sessionData + "]"; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cxdx/CxDxServerSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.cxdx; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.cxdx.ServerCxDxSession; import org.jdiameter.api.cxdx.ServerCxDxSessionListener; import org.jdiameter.api.cxdx.events.JLocationInfoAnswer; import org.jdiameter.api.cxdx.events.JLocationInfoRequest; import org.jdiameter.api.cxdx.events.JMultimediaAuthAnswer; import org.jdiameter.api.cxdx.events.JMultimediaAuthRequest; import org.jdiameter.api.cxdx.events.JPushProfileAnswer; import org.jdiameter.api.cxdx.events.JPushProfileRequest; import org.jdiameter.api.cxdx.events.JRegistrationTerminationAnswer; import org.jdiameter.api.cxdx.events.JRegistrationTerminationRequest; import org.jdiameter.api.cxdx.events.JServerAssignmentAnswer; import org.jdiameter.api.cxdx.events.JServerAssignmentRequest; import org.jdiameter.api.cxdx.events.JUserAuthorizationAnswer; import org.jdiameter.api.cxdx.events.JUserAuthorizationRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.cxdx.CxDxSessionState; import org.jdiameter.common.api.app.cxdx.ICxDxMessageFactory; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.cxdx.CxDxSession; import org.jdiameter.server.impl.app.cxdx.Event.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Cx/Dx Server session implementation * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class CxDxServerSessionImpl extends CxDxSession implements ServerCxDxSession, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(CxDxServerSessionImpl.class); // Factories and Listeners -------------------------------------------------- private transient ServerCxDxSessionListener listener; protected long appId = -1; protected IServerCxDxSessionData sessionData; public CxDxServerSessionImpl(IServerCxDxSessionData sessionData, ICxDxMessageFactory fct, ISessionFactory sf, ServerCxDxSessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if ((this.appId = fct.getApplicationId()) < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } /* * (non-Javadoc) * * @see * org.jdiameter.api.cxdx.ServerCxDxSession#sendLocationInformationAnswer(org.jdiameter.api.cxdx.events.JLocationInfoAnswer) */ @Override public void sendLocationInformationAnswer(JLocationInfoAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } /* * (non-Javadoc) * * @see * org.jdiameter.api.cxdx.ServerCxDxSession#sendMultimediaAuthAnswer(org.jdiameter.api.cxdx.events.JMultimediaAuthAnswer) */ @Override public void sendMultimediaAuthAnswer(JMultimediaAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSession#sendServerAssignmentAnswer(org.jdiameter.api.cxdx.events. * JServerAssignmentAnswer) */ @Override public void sendServerAssignmentAnswer(JServerAssignmentAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSession#sendUserAuthorizationAnswer(org.jdiameter.api.cxdx.events. * JUserAuthorizationAnswer) */ @Override public void sendUserAuthorizationAnswer(JUserAuthorizationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSession#sendPushProfileRequest(org.jdiameter.api.cxdx.events.JPushProfileRequest) */ @Override public void sendPushProfileRequest(JPushProfileRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } /* * (non-Javadoc) * * @see org.jdiameter.api.cxdx.ServerCxDxSession#sendRegistrationTerminationRequest(org.jdiameter.api.cxdx.events. * JRegistrationTerminationRequest) */ @Override public void sendRegistrationTerminationRequest(JRegistrationTerminationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateMachine#getState(java.lang.Class) */ @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == CxDxSessionState.class ? (E) this.sessionData.getCxDxSessionState() : null; } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateMachine#handleEvent(org.jdiameter.api.app.StateEvent) */ @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final CxDxSessionState state = this.sessionData.getCxDxSessionState(); CxDxSessionState newState = null; Event localEvent = (Event) event; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVE_LIR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = CxDxSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doLocationInformationRequest(this, (JLocationInfoRequest) event.getData()); break; case RECEIVE_MAR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = CxDxSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doMultimediaAuthRequest(this, (JMultimediaAuthRequest) event.getData()); break; case RECEIVE_SAR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = CxDxSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doServerAssignmentRequest(this, (JServerAssignmentRequest) event.getData()); break; case RECEIVE_UAR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = CxDxSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doUserAuthorizationRequest(this, (JUserAuthorizationRequest) event.getData()); break; case SEND_MESSAGE: super.session.send(((AppEvent) event.getData()).getMessage(), this); newState = CxDxSessionState.MESSAGE_SENT_RECEIVED; setState(newState); break; default: logger.error("Wrong action in Cx/Dx Server FSM. State: IDLE, Event Type: {}", eventType); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = CxDxSessionState.TIMEDOUT; break; case SEND_MESSAGE: try { super.session.send(((AppEvent) event.getData()).getMessage(), this); } finally { newState = CxDxSessionState.TERMINATED; setState(newState); } break; case RECEIVE_PPA: try { super.cancelMsgTimer(); listener.doPushProfileAnswer(this, (JPushProfileRequest) localEvent.getRequest(), (JPushProfileAnswer) localEvent.getAnswer()); } finally { newState = CxDxSessionState.TERMINATED; setState(newState); } break; case RECEIVE_RTA: try { super.cancelMsgTimer(); listener.doRegistrationTerminationAnswer(this, (JRegistrationTerminationRequest) localEvent.getRequest(), (JRegistrationTerminationAnswer) localEvent.getAnswer()); } finally { newState = CxDxSessionState.TERMINATED; setState(newState); } break; default: throw new InternalException( "Should not receive more messages after initial. Command: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("Cx/Dx Server FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } /* * (non-Javadoc) * * @see * org.jdiameter.api.EventListener#receivedSuccessMessage(org.jdiameter. * api.Message, org.jdiameter.api.Message) */ @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } /* * (non-Javadoc) * * @see org.jdiameter.api.EventListener#timeoutExpired(org.jdiameter.api.Message) */ @Override public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } /* * (non-Javadoc) * * @see org.jdiameter.api.NetworkReqListener#processRequest(org.jdiameter.api.Request) */ @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } @SuppressWarnings("unchecked") protected void setState(CxDxSessionState newState) { CxDxSessionState oldState = this.sessionData.getCxDxSessionState(); this.sessionData.setCxDxSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == CxDxSessionState.TERMINATED || newState == CxDxSessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); } } @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(CxDxSession.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } private class RequestDelivery implements Runnable { ServerCxDxSession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case JUserAuthorizationRequest.code: handleEvent(new Event(Event.Type.RECEIVE_UAR, messageFactory.createUserAuthorizationRequest(request), null)); break; case JServerAssignmentRequest.code: handleEvent( new Event(Event.Type.RECEIVE_SAR, messageFactory.createServerAssignmentRequest(request), null)); break; case JMultimediaAuthRequest.code: handleEvent( new Event(Event.Type.RECEIVE_MAR, messageFactory.createMultimediaAuthRequest(request), null)); break; case JLocationInfoRequest.code: handleEvent(new Event(Event.Type.RECEIVE_LIR, messageFactory.createLocationInfoRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerCxDxSession session; Answer answer; Request request; @Override public void run() { try { switch (answer.getCommandCode()) { case JPushProfileAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_PPA, messageFactory.createPushProfileRequest(request), messageFactory.createPushProfileAnswer(answer))); break; case JRegistrationTerminationAnswer.code: handleEvent( new Event(Event.Type.RECEIVE_RTA, messageFactory.createRegistrationTerminationRequest(request), messageFactory.createRegistrationTerminationAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cxdx/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.cxdx; import org.jdiameter.api.InternalException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * Start time:19:52:21 2009-08-17
      * Project: diameter-parent
      * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_UAR, RECEIVE_SAR, RECEIVE_LIR, RECEIVE_MAR, RECEIVE_PPA, RECEIVE_RTA; } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateEvent#setData(java.lang.Object) */ @Override public void setData(Object data) { try { if (((AppEvent) data).getMessage().isRequest()) { request = (AppEvent) data; } else { answer = (AppEvent) data; } } catch (InternalException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cxdx/IServerCxDxSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.cxdx; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerCxDxSessionData extends ICxDxSessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/cxdx/ServerCxDxSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.cxdx; import org.jdiameter.common.impl.app.cxdx.CxDxLocalSessionDataImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ServerCxDxSessionDataLocalImpl extends CxDxLocalSessionDataImpl implements IServerCxDxSessionData { /** * */ public ServerCxDxSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/gq/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.gq; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Yulian Oifa * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class Event implements StateEvent { enum Type { RECEIVE_AUTH_REQUEST, SEND_AUTH_ANSWER, RECEIVE_STR_REQUEST, SEND_STR_ANSWER, SEND_ASR_REQUEST, SEND_ASR_FAILURE, RECEIVE_ASR_ANSWER, SEND_RAR_REQUEST, SEND_RAR_FAILURE, RECEIVE_RAR_ANSWER, TIMEOUT_EXPIRES } Type type; AppEvent data; Event(Type type, AppEvent data) { this.type = type; this.data = data; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public void setData(Object o) { data = (AppEvent) o; } @Override public Object getData() { return data; } @Override public int compareTo(Object o) { return 0; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/gq/GqServerSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.gq; import static org.jdiameter.common.api.app.auth.ServerAuthSessionState.*; import static org.jdiameter.server.impl.app.gq.Event.Type.*; import java.io.Serializable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.auth.ServerAuthSessionListener; import org.jdiameter.api.auth.events.AbortSessionAnswer; import org.jdiameter.api.auth.events.AbortSessionRequest; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.auth.events.SessionTermAnswer; import org.jdiameter.api.auth.events.SessionTermRequest; import org.jdiameter.api.gq.GqServerSession; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.auth.IAuthMessageFactory; import org.jdiameter.common.api.app.auth.IServerAuthActionContext; import org.jdiameter.common.api.app.auth.ServerAuthSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.auth.AbortSessionAnswerImpl; import org.jdiameter.common.impl.app.auth.AbortSessionRequestImpl; import org.jdiameter.common.impl.app.auth.AppAuthSessionImpl; import org.jdiameter.common.impl.app.auth.ReAuthAnswerImpl; import org.jdiameter.common.impl.app.auth.ReAuthRequestImpl; import org.jdiameter.common.impl.app.auth.SessionTermRequestImpl; import org.jdiameter.server.impl.app.auth.IServerAuthSessionData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Server Gq Application session implementation * * @author Yulian Oifa * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class GqServerSessionImpl extends AppAuthSessionImpl implements GqServerSession, EventListener, NetworkReqListener { protected static final Logger logger = LoggerFactory.getLogger(GqServerSessionImpl.class); protected IServerAuthSessionData sessionData; // Session State Handling --------------------------------------------------- private Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IAuthMessageFactory factory; protected transient IServerAuthActionContext context; protected transient ServerAuthSessionListener listener; // Ts Timer ----------------------------------------------------------------- protected static final String TIMER_NAME_TS = "GQ_TS"; // Constructors ------------------------------------------------------------- public GqServerSessionImpl(IServerAuthSessionData sessionData, ISessionFactory sf, ServerAuthSessionListener lst, IAuthMessageFactory fct, StateChangeListener scListener, IServerAuthActionContext context, long tsTimeout, boolean stateless) { super(sf, sessionData); super.appId = fct.getApplicationId(); this.listener = lst; this.factory = fct; this.context = context; this.sessionData = sessionData; this.sessionData.setStateless(stateless); this.sessionData.setTsTimeout(tsTimeout); super.addStateChangeNotification(scListener); } // ServerAuthSession Implementation methods --------------------------------- @Override public void sendAuthAnswer(AppAnswerEvent appAnswerEvent) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(null, appAnswerEvent); } @Override public void sendReAuthRequest(ReAuthRequest reAuthRequest) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(null, reAuthRequest); } @Override public void sendAbortSessionRequest(AbortSessionRequest abortSessionRequest) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_ASR_REQUEST, abortSessionRequest); } @Override public void sendSessionTerminationAnswer(SessionTermAnswer sessionTermAnswer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { sendPost(Event.Type.SEND_STR_ANSWER, sessionTermAnswer); } protected void sendPost(Event.Type type, AppEvent event) throws InternalException { try { sendAndStateLock.lock(); session.send(event.getMessage(), this); if (type != null) { handleEvent(new Event(type, event)); } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } protected void send(Event.Type type, AppEvent event) throws InternalException { try { sendAndStateLock.lock(); if (type != null) { handleEvent(new Event(type, event)); } session.send(event.getMessage(), this); } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } @Override public boolean isStateless() { return sessionData.isStateless(); } @SuppressWarnings("unchecked") protected void setState(ServerAuthSessionState newState) { IAppSessionState oldState = sessionData.getServerAuthSessionState(); sessionData.setServerAuthSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } } @Override @SuppressWarnings("unchecked") public E getState(Class eClass) { return eClass == ServerAuthSessionState.class ? (E) sessionData.getServerAuthSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return isStateless() ? handleEventForStatelessSession(event) : handleEventForStatefullSession(event); } public boolean handleEventForStatelessSession(StateEvent event) throws InternalException, OverloadException { try { switch (sessionData.getServerAuthSessionState()) { case IDLE: switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_REQUEST: // Current State: IDLE // Event: Service-specific authorization request received, and successfully processed // Action: Send service specific answer // New State: IDLE listener.doAuthRequestEvent(this, (AppRequestEvent) event.getData()); setState(IDLE); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } } catch (Throwable t) { throw new InternalException(t); } return true; } public boolean handleEventForStatefullSession(StateEvent event) throws InternalException, OverloadException { ServerAuthSessionState state = sessionData.getServerAuthSessionState(); ServerAuthSessionState oldState = state; try { switch (state) { case IDLE: { switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_REQUEST: try { // Current State: IDLE // Event: Service-specific authorization request received, and user is authorized // Action: Send successful service specific answer // New State: OPEN listener.doAuthRequestEvent(this, (AppRequestEvent) event.getData()); setState(OPEN); } catch (Exception e) { setState(IDLE); } break; case RECEIVE_STR_REQUEST: try { // Current State: ANY // Event: STR Received // Action: Send STA, Cleanup // New State: IDLE listener.doSessionTerminationRequestEvent(this, (SessionTermRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } break; case SEND_ASR_REQUEST: setState(DISCONNECTED); break; case SEND_STR_ANSWER: setState(IDLE); break; case TIMEOUT_EXPIRES: if (context != null) { context.accessTimeoutElapses(this); } setState(IDLE); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } case OPEN: { switch ((Event.Type) event.getType()) { case RECEIVE_AUTH_REQUEST: try { // Current State: OPEN // Event: Service-specific authorization request received, and user is authorized // Action: Send successful service specific answer // New State: OPEN listener.doAuthRequestEvent(this, (AppRequestEvent) event.getData()); } catch (Exception e) { // Current State: OPEN // Event: Service-specific authorization request received, and user is not authorized // Action: Send failed service specific answer, Cleanup // New State: IDLE setState(IDLE); } break; case RECEIVE_STR_REQUEST: try { listener.doSessionTerminationRequestEvent(this, (SessionTermRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } break; case SEND_ASR_REQUEST: // Current State: OPEN // Event: Home server wants to terminate the service // Action: Send ASR // New State: DISCON setState(DISCONNECTED); break; case SEND_STR_ANSWER: setState(IDLE); break; case TIMEOUT_EXPIRES: // Current State: OPEN // Event: Authorization-Lifetime (and Auth-Grace-Period) expires on home server. // Action: Cleanup // New State: IDLE // Current State: OPEN // Event: Session-Timeout expires on home server // Action: Cleanup // New State: IDLE if (context != null) { context.accessTimeoutElapses(this); } setState(IDLE); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } case DISCONNECTED: { switch ((Event.Type) event.getType()) { case SEND_ASR_FAILURE: // Current State: DISCON // Event: Failure to send ASR // Action: Wait, Re-send ASR // New State: DISCON setState(DISCONNECTED); break; case RECEIVE_ASR_ANSWER: // Current State: DISCON // Event: ASR successfully sent and ASA Received with Result-Code // Action: Cleanup // New State: DISCON listener.doAbortSessionAnswerEvent(this, (AbortSessionAnswer) event.getData()); //setState(IDLE); break; case RECEIVE_STR_REQUEST: try { listener.doSessionTerminationRequestEvent(this, (SessionTermRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } break; case SEND_STR_ANSWER: setState(IDLE); break; default: logger.debug("Unknown event {}", event.getType()); break; } break; } default: { logger.debug("Unknown state {}", state); break; } } // post processing if (oldState != state) { if (OPEN.equals(state) && context != null) { if (context != null) { cancelTsTimer(); startTsTimer(); } } } } catch (Throwable t) { throw new InternalException(t); } return true; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } @Override public void timeoutExpired(Request request) { try { if (request.getCommandCode() == AbortSessionRequest.code) { handleEvent(new Event(Event.Type.SEND_ASR_FAILURE, new AbortSessionRequestImpl(request))); } else { logger.debug("Timeout for unknown request {}", request); } } catch (Exception e) { logger.debug("Can not handle event", e); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } protected void startTsTimer() { try { sendAndStateLock.lock(); if (sessionData.getTsTimeout() > 0) { sessionData.setTsTimerId( super.timerFacility.schedule(sessionData.getSessionId(), TIMER_NAME_TS, sessionData.getTsTimeout())); } } finally { sendAndStateLock.unlock(); } } protected void cancelTsTimer() { try { sendAndStateLock.lock(); Serializable tsTimerId = sessionData.getTsTimerId(); if (tsTimerId != null) { super.timerFacility.cancel(tsTimerId); sessionData.setTsTimerId(null); } } finally { sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TIMER_NAME_TS)) { try { sendAndStateLock.lock(); sessionData.setTsTimerId(null); handleEvent(new Event(TIMEOUT_EXPIRES, null)); } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } protected ReAuthAnswer createReAuthAnswer(Answer answer) { return new ReAuthAnswerImpl(answer); } protected ReAuthRequest createReAuthRequest(Request request) { return new ReAuthRequestImpl(request); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } GqServerSessionImpl other = (GqServerSessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } private class RequestDelivery implements Runnable { GqServerSession session; Request request; @Override public void run() { if (request != null) { try { sendAndStateLock.lock(); if (request.getCommandCode() == factory.getAuthMessageCommandCode()) { handleEvent(new Event(RECEIVE_AUTH_REQUEST, factory.createAuthRequest(request))); } else if (request.getCommandCode() == SessionTermRequest.code) { handleEvent(new Event(RECEIVE_STR_REQUEST, new SessionTermRequestImpl(request))); } else { listener.doOtherEvent(session, factory.createAuthRequest(request), null); } } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } } } } private class AnswerDelivery implements Runnable { GqServerSession session; Answer answer; Request request; @Override public void run() { try { sendAndStateLock.lock(); if (request.getCommandCode() == ReAuthRequest.code) { listener.doReAuthAnswerEvent(session, createReAuthRequest(request), createReAuthAnswer(answer)); } else if (request.getCommandCode() == AbortSessionRequest.code) { handleEvent(new Event(RECEIVE_ASR_ANSWER, new AbortSessionAnswerImpl(answer))); } else { listener.doOtherEvent(session, factory.createAuthRequest(request), new AppAnswerEventImpl(answer)); } } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/gx/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.gx; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.gx.events.GxCreditControlAnswer; import org.jdiameter.api.gx.events.GxCreditControlRequest; /** * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { public enum Type { RECEIVED_EVENT, SENT_EVENT_RESPONSE, RECEIVED_INITIAL, SENT_INITIAL_RESPONSE, RECEIVED_UPDATE, SENT_UPDATE_RESPONSE, RECEIVED_TERMINATE, SENT_TERMINATE_RESPONSE, // These have no transition, no state resources, timers SENT_RAR, RECEIVED_RAA; } Type type; AppRequestEvent request; AppAnswerEvent answer; Event(Type type) { this.type = type; } Event(Type type, AppRequestEvent request, AppAnswerEvent answer) { this.type = type; this.answer = answer; this.request = request; } Event(boolean isRequest, GxCreditControlRequest request, GxCreditControlAnswer answer) { this.answer = answer; this.request = request; /** *
               * 8.3.  CC-Request-Type AVP
               *
               *     The CC-Request-Type AVP (AVP Code 416) is of type Enumerated and
               *     contains the reason for sending the credit-control request message.
               *     It MUST be present in all Credit-Control-Request messages.  The
               *     following values are defined for the CC-Request-Type AVP:
               *
               *     INITIAL_REQUEST                 1
               *     UPDATE_REQUEST                  2
               *     TERMINATION_REQUEST             3
               *     EVENT_REQUEST                   4
               * 
      */ if (isRequest) { switch (request.getRequestTypeAVPValue()) { case 1: type = Type.RECEIVED_INITIAL; break; case 2: type = Type.RECEIVED_UPDATE; break; case 3: type = Type.RECEIVED_TERMINATE; break; case 4: type = Type.RECEIVED_EVENT; break; default: throw new IllegalArgumentException("Invalid value or Request-Type AVP not present in CC Request."); } } else { switch (answer.getRequestTypeAVPValue()) { case 1: type = Type.SENT_INITIAL_RESPONSE; break; case 2: type = Type.SENT_UPDATE_RESPONSE; break; case 3: type = Type.SENT_TERMINATE_RESPONSE; break; case 4: type = Type.SENT_EVENT_RESPONSE; break; default: throw new IllegalArgumentException("Invalid value or Request-Type AVP not present in CC Answer."); } } } @Override public E encodeType(Class eClass) { return eClass == Event.Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return this.request != null ? this.request : this.answer; } @Override public void setData(Object data) { // data = (AppEvent) o; // FIXME: What should we do here?! Is it request or answer? } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/gx/IServerGxSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.gx; import java.io.Serializable; import org.jdiameter.common.api.app.gx.IGxSessionData; import org.jdiameter.common.api.app.gx.ServerGxSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerGxSessionData extends IGxSessionData { boolean isStateless(); void setStateless(boolean stateless); ServerGxSessionState getServerGxSessionState(); void setServerGxSessionState(ServerGxSessionState state); void setTccTimerId(Serializable tccTimerId); Serializable getTccTimerId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/gx/ServerGxSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.gx; import java.io.Serializable; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.gx.ServerGxSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ServerGxSessionDataLocalImpl extends AppSessionDataLocalImpl implements IServerGxSessionData { protected boolean stateless = true; protected ServerGxSessionState state = ServerGxSessionState.IDLE; protected Serializable tccTimerId; /** * */ public ServerGxSessionDataLocalImpl() { } @Override public boolean isStateless() { return stateless; } @Override public void setStateless(boolean stateless) { this.stateless = stateless; } @Override public ServerGxSessionState getServerGxSessionState() { return state; } @Override public void setServerGxSessionState(ServerGxSessionState state) { this.state = state; } @Override public Serializable getTccTimerId() { return tccTimerId; } @Override public void setTccTimerId(Serializable tccTimerId) { this.tccTimerId = tccTimerId; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/gx/ServerGxSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.gx; import java.io.Serializable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.gx.ServerGxSession; import org.jdiameter.api.gx.ServerGxSessionListener; import org.jdiameter.api.gx.events.GxCreditControlAnswer; import org.jdiameter.api.gx.events.GxCreditControlRequest; import org.jdiameter.api.gx.events.GxReAuthAnswer; import org.jdiameter.api.gx.events.GxReAuthRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.gx.IGxMessageFactory; import org.jdiameter.common.api.app.gx.IServerGxSessionContext; import org.jdiameter.common.api.app.gx.ServerGxSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.gx.AppGxSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Credit Control Application Server session implementation * * @author Alexandre Mendonca * @author Bartosz Baranowski * @author Carl-Magnus Björkell */ @SuppressWarnings("all") //3rd party lib public class ServerGxSessionImpl extends AppGxSessionImpl implements ServerGxSession, NetworkReqListener, EventListener { private static final Logger logger = LoggerFactory.getLogger(ServerGxSessionImpl.class); // Session State Handling --------------------------------------------------- protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IGxMessageFactory factory = null; protected transient IServerGxSessionContext context = null; protected transient ServerGxSessionListener listener = null; protected static final String TCC_TIMER_NAME = "TCC_GxSERVER_TIMER"; protected long[] authAppIds = new long[] { 4 }; //protected String originHost, originRealm; protected IServerGxSessionData sessionData; public ServerGxSessionImpl(IServerGxSessionData sessionData, IGxMessageFactory fct, ISessionFactory sf, ServerGxSessionListener lst, IServerGxSessionContext ctx, StateChangeListener stLst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationIds() == null) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } context = ctx; authAppIds = fct.getApplicationIds(); listener = lst; factory = fct; this.sessionData = sessionData; super.addStateChangeNotification(stLst); } @Override public void sendCreditControlAnswer(GxCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { handleEvent(new Event(false, null, answer)); } @Override public void sendGxReAuthRequest(GxReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SENT_RAR, request, null); } @Override public boolean isStateless() { return this.sessionData.isStateless(); } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == ServerGxSessionState.class ? (E) this.sessionData.getServerGxSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { ServerGxSessionState newState = null; try { sendAndStateLock.lock(); // Can be null if there is no state transition, transition to IDLE state should terminate this app session final Event localEvent = (Event) event; final ServerGxSessionState state = this.sessionData.getServerGxSessionState(); //Its kind of awkward, but with two state on server side its easier to go through event types? //but for sake of FSM readability final Event.Type eventType = (Event.Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVED_INITIAL: listener.doCreditControlRequest(this, (GxCreditControlRequest) localEvent.getRequest()); break; case RECEIVED_EVENT: // Current State: IDLE // Event: CC event request received and successfully processed // Action: Send CC event answer // New State: IDLE listener.doCreditControlRequest(this, (GxCreditControlRequest) localEvent.getRequest()); break; case SENT_EVENT_RESPONSE: // Current State: IDLE // Event: CC event request received and successfully processed // Action: Send CC event answer // New State: IDLE // Current State: IDLE // Event: CC event request received but not successfully processed // Action: Send CC event answer with Result-Code != SUCCESS // New State: IDLE newState = ServerGxSessionState.IDLE; dispatchEvent(localEvent.getAnswer()); setState(newState); break; case SENT_INITIAL_RESPONSE: GxCreditControlAnswer answer = (GxCreditControlAnswer) localEvent.getAnswer(); try { long resultCode = answer.getResultCodeAvp().getUnsigned32(); // Current State: IDLE // Event: CC initial request received and successfully processed // Action: Send CC initial answer, reserve units, start Tcc // New State: OPEN if (isSuccess(resultCode)) { startTcc(answer.getValidityTimeAvp()); newState = ServerGxSessionState.OPEN; } // Current State: IDLE // Event: CC initial request received but not successfully processed // Action: Send CC initial answer with Result-Code != SUCCESS // New State: IDLE else { newState = ServerGxSessionState.IDLE; } dispatchEvent(localEvent.getAnswer()); setState(newState); } catch (AvpDataException e) { throw new InternalException(e); } break; default: throw new InternalException("Wrong state: " + ServerGxSessionState.IDLE + " one event: " + eventType + " " + localEvent.getRequest() + " " + localEvent.getAnswer()); } case OPEN: switch (eventType) { /* * This should not happen, it should be silently discarded, right? * case RECEIVED_INITIAL: * // only for rtr * if (((RoRequest) localEvent.getRequest()).getMessage().isReTransmitted()) { * listener.doCreditControlRequest(this, (RoRequest) localEvent.getRequest()); * } * else { * //do nothing? * } * break; */ case RECEIVED_UPDATE: listener.doCreditControlRequest(this, (GxCreditControlRequest) localEvent.getRequest()); break; case SENT_UPDATE_RESPONSE: GxCreditControlAnswer answer = (GxCreditControlAnswer) localEvent.getAnswer(); try { if (isSuccess(answer.getResultCodeAvp().getUnsigned32())) { // Current State: OPEN // Event: CC update request received and successfully processed // Action: Send CC update answer, debit used units, reserve new units, restart Tcc // New State: OPEN startTcc(answer.getValidityTimeAvp()); } else { // Current State: OPEN // Event: CC update request received but not successfully processed // Action: Send CC update answer with Result-Code != SUCCESS, debit used units // New State: IDLE // It's a failure, we wait for Tcc to fire -- FIXME: Alexandre: Should we? newState = ServerGxSessionState.IDLE; } } catch (AvpDataException e) { throw new InternalException(e); } dispatchEvent(localEvent.getAnswer()); if (newState != null) { setState(newState); } break; case RECEIVED_TERMINATE: listener.doCreditControlRequest(this, (GxCreditControlRequest) localEvent.getRequest()); break; case SENT_TERMINATE_RESPONSE: answer = (GxCreditControlAnswer) localEvent.getAnswer(); try { // Current State: OPEN // Event: CC termination request received and successfully processed // Action: Send CC termination answer, Stop Tcc, debit used units // New State: IDLE if (isSuccess(answer.getResultCodeAvp().getUnsigned32())) { stopTcc(false); } else { // Current State: OPEN // Event: CC termination request received but not successfully processed // Action: Send CC termination answer with Result-Code != SUCCESS, debit used units // New State: IDLE // It's a failure, we wait for Tcc to fire -- FIXME: Alexandre: Should we? } } catch (AvpDataException e) { throw new InternalException(e); } newState = ServerGxSessionState.IDLE; dispatchEvent(localEvent.getAnswer()); setState(newState); break; case RECEIVED_RAA: listener.doGxReAuthAnswer(this, (GxReAuthRequest) localEvent.getRequest(), (GxReAuthAnswer) localEvent.getAnswer()); break; case SENT_RAR: dispatchEvent(localEvent.getRequest()); break; } } return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } private class TccScheduledTask implements Runnable { ServerGxSession session = null; private TccScheduledTask(ServerGxSession session) { super(); this.session = session; } @Override public void run() { // Current State: OPEN // Event: Session supervision timer Tcc expired // Action: Release reserved units // New State: IDLE context.sessionSupervisionTimerExpired(session); try { sendAndStateLock.lock(); // tccFuture = null; sessionData.setTccTimerId(null); setState(ServerGxSessionState.IDLE); } finally { sendAndStateLock.unlock(); } } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); //rd.session = (ServerGxSession) LocalDataSource.INSTANCE.getSession(request.getSessionId()); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } @Override public void timeoutExpired(Request request) { context.timeoutExpired(request); //FIXME: Should we release ? } private void startTcc(Avp validityAvp) { // There is no Validity-Time //long tccTimeout; // //if(validityAvp != null) { // try { // tccTimeout = 2 * validityAvp.getUnsigned32(); // } // catch (AvpDataException e) { // logger.debug("Unable to retrieve Validity-Time AVP value, using default.", e); // tccTimeout = 2 * context.getDefaultValidityTime(); // } //} //else { // tccTimeout = 2 * context.getDefaultValidityTime(); //} // //if(tccTimerId != null) { // stopTcc(true); // //tccFuture = super.scheduler.schedule(new TccScheduledTask(this), defaultValue, TimeUnit.SECONDS); // tccTimerId = super.timerFacility.schedule(this.sessionId, TCC_TIMER_NAME, tccTimeout * 1000); // // FIXME: this accepts Future! // context.sessionSupervisionTimerReStarted(this, null); //} //else { // //tccFuture = super.scheduler.schedule(new TccScheduledTask(this), defaultValue, TimeUnit.SECONDS); // tccTimerId = super.timerFacility.schedule(this.sessionId, TCC_TIMER_NAME, tccTimeout * 1000); // //FIXME: this accepts Future! // context.sessionSupervisionTimerStarted(this, null); //} //super.sessionDataSource.updateSession(this); } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TCC_TIMER_NAME)) { new TccScheduledTask(this).run(); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } private void stopTcc(boolean willRestart) { final Serializable tccTimerId = this.sessionData.getTccTimerId(); if (tccTimerId != null) { super.timerFacility.cancel(tccTimerId); this.sessionData.setTccTimerId(null); if (!willRestart && context != null) { context.sessionSupervisionTimerStopped(this, null); } } } protected boolean isProvisional(long resultCode) { return resultCode >= 1000 && resultCode < 2000; } protected boolean isSuccess(long resultCode) { return resultCode >= 2000 && resultCode < 3000; } protected void setState(ServerGxSessionState newState) { setState(newState, true); } @SuppressWarnings("unchecked") protected void setState(ServerGxSessionState newState, boolean release) { IAppSessionState oldState = this.sessionData.getServerGxSessionState(); this.sessionData.setServerGxSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == ServerGxSessionState.IDLE) { stopTcc(false); if (release) { // NOTE: do EVERYTHING before release. this.release(); } } } @Override public void release() { if (isValid()) { try { this.sendAndStateLock.lock(); this.stopTcc(false); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void send(Event.Type type, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { try { sendAndStateLock.lock(); if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } protected void dispatchEvent(AppEvent event) throws InternalException { try { session.send(event.getMessage(), this); // Store last destination information } catch (Exception e) { throw new InternalException(e); // logger.debug("Failure trying to dispatch event", e); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } ServerGxSessionImpl other = (ServerGxSessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } private class RequestDelivery implements Runnable { ServerGxSession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case GxCreditControlAnswer.code: handleEvent(new Event(true, factory.createCreditControlRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerGxSession session; Answer answer; Request request; @Override public void run() { try { // FIXME: baranowb: add message validation here!!! // We handle CCR, STR, ACR, ASR other go into extension switch (request.getCommandCode()) { case GxReAuthRequest.code: handleEvent(new Event(Event.Type.RECEIVED_RAA, factory.createGxReAuthRequest(request), factory.createGxReAuthAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/rf/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.rf; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.rf.events.RfAccountingRequest; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib class Event implements StateEvent { enum Type { RECEIVED_EVENT_RECORD, RECEIVED_START_RECORD, RECEIVED_INTERIM_RECORD, RECEIVED_STOP_RECORD } Type type; AppEvent data; Event(Type type) { this.type = type; } Event(RfAccountingRequest accountRequest) throws Exception { data = accountRequest; int type = accountRequest.getAccountingRecordType(); switch (type) { case 1: this.type = Type.RECEIVED_EVENT_RECORD; break; case 2: this.type = Type.RECEIVED_START_RECORD; break; case 3: this.type = Type.RECEIVED_INTERIM_RECORD; break; case 4: this.type = Type.RECEIVED_STOP_RECORD; break; default: throw new Exception("Unknown type " + type); } } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public void setData(Object o) { data = (AppEvent) o; } @Override public Object getData() { return data; } @Override public int compareTo(Object other) { return equals(other) ? 0 : -1; } @Override public int hashCode() { return super.hashCode(); } @Override public boolean equals(Object other) { return this == other; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/rf/IServerRfSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.rf; import java.io.Serializable; import org.jdiameter.common.api.app.rf.IRfSessionData; import org.jdiameter.common.api.app.rf.ServerRfSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerRfSessionData extends IRfSessionData { ServerRfSessionState getServerRfSessionState(); void setServerRfSessionState(ServerRfSessionState state); void setTsTimerId(Serializable tsTimerId); Serializable getTsTimerId(); long getTsTimeout(); void setTsTimeout(long tsTimeout); boolean isStateless(); void setStateless(boolean stateless); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/rf/ServerRfSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.rf; import java.io.Serializable; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.rf.ServerRfSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ServerRfSessionDataLocalImpl extends AppSessionDataLocalImpl implements IServerRfSessionData { protected boolean stateless = true; protected ServerRfSessionState state = ServerRfSessionState.IDLE; protected Serializable tsTimerId; protected long tsTimeout = NON_INITIALIZED; /** * */ public ServerRfSessionDataLocalImpl() { } @Override public boolean isStateless() { return stateless; } @Override public void setStateless(boolean stateless) { this.stateless = stateless; } @Override public ServerRfSessionState getServerRfSessionState() { return state; } @Override public void setServerRfSessionState(ServerRfSessionState state) { this.state = state; } @Override public Serializable getTsTimerId() { return tsTimerId; } @Override public void setTsTimerId(Serializable tsTimerId) { this.tsTimerId = tsTimerId; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.rf.IServerRfSessionData#getTsTimeout() */ @Override public long getTsTimeout() { return this.tsTimeout; } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.rf.IServerRfSessionData#setTsTimeout(long) */ @Override public void setTsTimeout(long tsTimeout) { this.tsTimeout = tsTimeout; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/rf/ServerRfSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.rf; import static org.jdiameter.common.api.app.rf.ServerRfSessionState.IDLE; import static org.jdiameter.common.api.app.rf.ServerRfSessionState.OPEN; import java.io.Serializable; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.ResultCode; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.rf.ServerRfSession; import org.jdiameter.api.rf.ServerRfSessionListener; import org.jdiameter.api.rf.events.RfAccountingAnswer; import org.jdiameter.api.rf.events.RfAccountingRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.rf.IServerRfActionContext; import org.jdiameter.common.api.app.rf.ServerRfSessionState; import org.jdiameter.common.impl.app.rf.AppRfSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Server Accounting session implementation * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ServerRfSessionImpl extends AppRfSessionImpl implements EventListener, ServerRfSession, NetworkReqListener { //FIXME: verify this FSM private static final long serialVersionUID = 1L; private static final Logger logger = LoggerFactory.getLogger(ServerRfSessionImpl.class); // Session State Handling --------------------------------------------------- // Factories and Listeners -------------------------------------------------- protected transient IServerRfActionContext context; protected transient ServerRfSessionListener listener; // Ts Timer ----------------------------------------------------------------- protected static final String TIMER_NAME_TS = "TS"; protected IServerRfSessionData sessionData; // Constructors ------------------------------------------------------------- public ServerRfSessionImpl(IServerRfSessionData sessionData, ISessionFactory sessionFactory, ServerRfSessionListener serverSessionListener, IServerRfActionContext serverContextListener, StateChangeListener stLst, long tsTimeout, boolean stateless) { // TODO Auto-generated constructor stub super(sessionFactory, sessionData); this.listener = serverSessionListener; this.context = serverContextListener; this.sessionData = sessionData; this.sessionData.setTsTimeout(tsTimeout); this.sessionData.setStateless(stateless); super.addStateChangeNotification(stLst); } @Override public void sendAccountAnswer(RfAccountingAnswer accountAnswer) throws InternalException, IllegalStateException, RouteException, OverloadException { try { session.send(accountAnswer.getMessage()); /* * TODO: Need to notify state change... * if (isStateless() && isValid()) { * session.release(); * } */ } catch (IllegalDiameterStateException e) { throw new IllegalStateException(e); } } @Override public boolean isStateless() { return this.sessionData.isStateless(); } @SuppressWarnings("unchecked") protected void setState(IAppSessionState newState) { IAppSessionState oldState = this.sessionData.getServerRfSessionState(); this.sessionData.setServerRfSessionState((ServerRfSessionState) newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { return isStateless() ? handleEventForStatelessMode(event) : handleEventForStatefulMode(event); } public boolean handleEventForStatelessMode(StateEvent event) throws InternalException, OverloadException { try { //this will handle RTRs as well, no need to alter. final ServerRfSessionState state = this.sessionData.getServerRfSessionState(); switch (state) { case IDLE: { switch ((Event.Type) event.getType()) { case RECEIVED_START_RECORD: // Current State: IDLE // Event: Accounting start request received, and successfully processed. // Action: Send accounting start answer // New State: IDLE if (listener != null) { try { listener.doRfAccountingRequestEvent(this, (RfAccountingRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } // TODO: This is unnecessary state change: setState(IDLE); break; case RECEIVED_EVENT_RECORD: // Current State: IDLE // Event: Accounting event request received, and successfully processed. // Action: Send accounting event answer // New State: IDLE if (listener != null) { try { listener.doRfAccountingRequestEvent(this, (RfAccountingRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } // FIXME: it is required, so we know it ends up again in IDLE! setState(IDLE); break; case RECEIVED_INTERIM_RECORD: // Current State: IDLE // Event: Interim record received, and successfully processed. // Action: Send accounting interim answer // New State: IDLE if (listener != null) { try { listener.doRfAccountingRequestEvent(this, (RfAccountingRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } // TODO: This is unnecessary state change: setState(IDLE); break; case RECEIVED_STOP_RECORD: // Current State: IDLE // Event: Accounting stop request received, and successfully processed // Action: Send accounting stop answer // New State: IDLE if (listener != null) { try { listener.doRfAccountingRequestEvent(this, (RfAccountingRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } // TODO: This is unnecessary state change: setState(IDLE); break; default: throw new IllegalStateException("Current state " + state + " action " + event.getType()); } } } } catch (Exception e) { logger.debug("Can not process event", e); return false; } finally { // TODO: Since setState was removed, we are now using this to terminate. Correct? // We can't release here, answer needs to be sent through. done at send. // release(); } return true; } public boolean handleEventForStatefulMode(StateEvent event) throws InternalException, OverloadException { try { if (((RfAccountingRequest) event.getData()).getMessage().isReTransmitted()) { try { setState(OPEN); listener.doRfAccountingRequestEvent(this, (RfAccountingRequest) event.getData()); // FIXME: should we do this before passing to lst? cancelTsTimer(); startTsTimer(); if (context != null) { context.sessionTimerStarted(this, null); } } catch (Exception e) { logger.debug("Can not handle event", e); setState(IDLE); } return true; } else { final ServerRfSessionState state = this.sessionData.getServerRfSessionState(); switch (state) { case IDLE: { switch ((Event.Type) event.getType()) { case RECEIVED_START_RECORD: // Current State: IDLE // Event: Accounting start request received, and successfully processed. // Action: Send accounting start answer, Start Ts // New State: OPEN setState(OPEN); if (listener != null) { try { listener.doRfAccountingRequestEvent(this, (RfAccountingRequest) event.getData()); cancelTsTimer(); startTsTimer(); if (context != null) { context.sessionTimerStarted(this, null); } } catch (Exception e) { logger.debug("Can not handle event", e); setState(IDLE); } } break; case RECEIVED_EVENT_RECORD: // Current State: IDLE // Event: Accounting event request received, and // successfully processed. // Action: Send accounting event answer // New State: IDLE if (listener != null) { try { listener.doRfAccountingRequestEvent(this, (RfAccountingRequest) event.getData()); } catch (Exception e) { logger.debug("Can not handle event", e); } } break; } break; } case OPEN: { switch ((Event.Type) event.getType()) { case RECEIVED_INTERIM_RECORD: // Current State: OPEN // Event: Interim record received, and successfully // processed. // Action: Send accounting interim answer, Restart Ts // New State: OPEN try { listener.doRfAccountingRequestEvent(this, (RfAccountingRequest) event.getData()); cancelTsTimer(); startTsTimer(); if (context != null) { context.sessionTimerStarted(this, null); } } catch (Exception e) { logger.debug("Can not handle event", e); setState(IDLE); } break; case RECEIVED_STOP_RECORD: // Current State: OPEN // Event: Accounting stop request received, and // successfully // processed // Action: Send accounting stop answer, Stop Ts // New State: IDLE setState(IDLE); try { listener.doRfAccountingRequestEvent(this, (RfAccountingRequest) event.getData()); cancelTsTimer(); if (context != null) { context.sessionTimerCanceled(this, null); } } catch (Exception e) { logger.debug("Can not handle event", e); setState(IDLE); } break; } break; } } } } catch (Exception e) { logger.debug("Can not process event", e); return false; } return true; } private void startTsTimer() { // return scheduler.schedule(new Runnable() { // public void run() { // logger.debug("Ts timer expired"); // if (context != null) { // try { // context.sessionTimeoutElapses(ServerRfSessionImpl.this); // } // catch (InternalException e) { // logger.debug("Failure on processing expired Ts", e); // } // } // setState(IDLE); // } // }, tsTimeout, TimeUnit.MILLISECONDS); try { sendAndStateLock.lock(); if (sessionData.getTsTimeout() > 0) { this.sessionData.setTsTimerId( super.timerFacility.schedule(getSessionId(), TIMER_NAME_TS, this.sessionData.getTsTimeout())); } } finally { sendAndStateLock.unlock(); } } private void cancelTsTimer() { try { sendAndStateLock.lock(); final Serializable tsTimerId = this.sessionData.getTsTimerId(); if (tsTimerId != null) { super.timerFacility.cancel(tsTimerId); this.sessionData.setTsTimerId(null); } } finally { sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TIMER_NAME_TS)) { if (context != null) { try { context.sessionTimeoutElapses(ServerRfSessionImpl.this); } catch (InternalException e) { logger.debug("Failure on processing expired Ts", e); } } setState(IDLE); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } protected Answer createStopAnswer(Request request) { Answer answer = request.createAnswer(ResultCode.SUCCESS); answer.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 4); answer.getAvps().addAvp(request.getAvps().getAvp(Avp.ACC_RECORD_NUMBER)); return answer; } protected Answer createInterimAnswer(Request request) { Answer answer = request.createAnswer(ResultCode.SUCCESS); answer.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 3); answer.getAvps().addAvp(request.getAvps().getAvp(Avp.ACC_RECORD_NUMBER)); return answer; } protected Answer createEventAnswer(Request request) { Answer answer = request.createAnswer(ResultCode.SUCCESS); answer.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 2); answer.getAvps().addAvp(request.getAvps().getAvp(Avp.ACC_RECORD_NUMBER)); return answer; } protected Answer createStartAnswer(Request request) { Answer answer = request.createAnswer(ResultCode.SUCCESS); answer.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 1); answer.getAvps().addAvp(request.getAvps().getAvp(Avp.ACC_RECORD_NUMBER)); return answer; } @Override @SuppressWarnings("unchecked") public E getState(Class eClass) { return eClass == ServerRfSessionState.class ? (E) this.sessionData.getServerRfSessionState() : null; } @Override public Answer processRequest(Request request) { if (request.getCommandCode() == RfAccountingRequest.code) { try { sendAndStateLock.lock(); handleEvent(new Event(createAccountRequest(request))); } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } } else { try { listener.doOtherEvent(this, createAccountRequest(request), null); } catch (Exception e) { logger.debug("Can not handle event", e); } } return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { if (request.getCommandCode() == RfAccountingRequest.code) { try { sendAndStateLock.lock(); handleEvent(new Event(createAccountRequest(request))); } catch (Exception e) { logger.debug("Can not handle event", e); } finally { sendAndStateLock.unlock(); } try { listener.doRfAccountingRequestEvent(this, createAccountRequest(request)); } catch (Exception e) { logger.debug("Can not handle event", e); } } else { try { listener.doOtherEvent(this, createAccountRequest(request), createAccountAnswer(answer)); } catch (Exception e) { logger.debug("Can not handle event", e); } } } @Override public void timeoutExpired(Request request) { // FIXME: alexandre: We don't do anything here... are we even getting this on server? } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); //TODO: cancel timer? super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/ro/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.ro; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.ro.events.RoCreditControlAnswer; import org.jdiameter.api.ro.events.RoCreditControlRequest; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { public enum Type { RECEIVED_EVENT, SENT_EVENT_RESPONSE, RECEIVED_INITIAL, SENT_INITIAL_RESPONSE, RECEIVED_UPDATE, SENT_UPDATE_RESPONSE, RECEIVED_TERMINATE, SENT_TERMINATE_RESPONSE, // These have no transition, no state resources, timers SENT_RAR, RECEIVED_RAA; } Type type; AppRequestEvent request; AppAnswerEvent answer; Event(Type type) { this.type = type; } Event(Type type, AppRequestEvent request, AppAnswerEvent answer) { this.type = type; this.answer = answer; this.request = request; } Event(boolean isRequest, RoCreditControlRequest request, RoCreditControlAnswer answer) { this.answer = answer; this.request = request; /** *
               * 8.3.  CC-Request-Type AVP
               *
               *     The CC-Request-Type AVP (AVP Code 416) is of type Enumerated and
               *     contains the reason for sending the credit-control request message.
               *     It MUST be present in all Credit-Control-Request messages.  The
               *     following values are defined for the CC-Request-Type AVP:
               *
               *     INITIAL_REQUEST                 1
               *     UPDATE_REQUEST                  2
               *     TERMINATION_REQUEST             3
               *     EVENT_REQUEST                   4
               * 
      */ if (isRequest) { switch (request.getRequestTypeAVPValue()) { case 1: type = Type.RECEIVED_INITIAL; break; case 2: type = Type.RECEIVED_UPDATE; break; case 3: type = Type.RECEIVED_TERMINATE; break; case 4: type = Type.RECEIVED_EVENT; break; default: throw new IllegalArgumentException("Invalid value or Request-Type AVP not present in CC Request."); } } else { switch (answer.getRequestTypeAVPValue()) { case 1: type = Type.SENT_INITIAL_RESPONSE; break; case 2: type = Type.SENT_UPDATE_RESPONSE; break; case 3: type = Type.SENT_TERMINATE_RESPONSE; break; case 4: type = Type.SENT_EVENT_RESPONSE; break; default: throw new IllegalArgumentException("Invalid value or Request-Type AVP not present in CC Answer."); } } } @Override public E encodeType(Class eClass) { return eClass == Event.Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return this.request != null ? this.request : this.answer; } @Override public void setData(Object data) { // data = (AppEvent) o; // FIXME: What should we do here?! Is it request or answer? } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/ro/IServerRoSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.ro; import java.io.Serializable; import org.jdiameter.common.api.app.ro.IRoSessionData; import org.jdiameter.common.api.app.ro.ServerRoSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IServerRoSessionData extends IRoSessionData { boolean isStateless(); void setStateless(boolean stateless); ServerRoSessionState getServerRoSessionState(); void setServerRoSessionState(ServerRoSessionState state); void setTccTimerId(Serializable tccTimerId); Serializable getTccTimerId(); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/ro/ServerRoSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.ro; import java.io.Serializable; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.ro.ServerRoSessionState; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ServerRoSessionDataLocalImpl extends AppSessionDataLocalImpl implements IServerRoSessionData { protected boolean stateless = true; protected ServerRoSessionState state = ServerRoSessionState.IDLE; protected Serializable tccTimerId; /** * */ public ServerRoSessionDataLocalImpl() { } @Override public boolean isStateless() { return stateless; } @Override public void setStateless(boolean stateless) { this.stateless = stateless; } @Override public ServerRoSessionState getServerRoSessionState() { return state; } @Override public void setServerRoSessionState(ServerRoSessionState state) { this.state = state; } @Override public Serializable getTccTimerId() { return tccTimerId; } @Override public void setTccTimerId(Serializable tccTimerId) { this.tccTimerId = tccTimerId; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/ro/ServerRoSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.ro; import java.io.Serializable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.ResultCode; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.ro.ServerRoSession; import org.jdiameter.api.ro.ServerRoSessionListener; import org.jdiameter.api.ro.events.RoCreditControlAnswer; import org.jdiameter.api.ro.events.RoCreditControlRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.ro.IRoMessageFactory; import org.jdiameter.common.api.app.ro.IServerRoSessionContext; import org.jdiameter.common.api.app.ro.ServerRoSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.auth.ReAuthAnswerImpl; import org.jdiameter.common.impl.app.auth.ReAuthRequestImpl; import org.jdiameter.common.impl.app.ro.AppRoSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Ro Application Server session implementation * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ServerRoSessionImpl extends AppRoSessionImpl implements ServerRoSession, NetworkReqListener, EventListener { private static final Logger logger = LoggerFactory.getLogger(ServerRoSessionImpl.class); // Session State Handling --------------------------------------------------- protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IRoMessageFactory factory = null; protected transient IServerRoSessionContext context = null; protected transient ServerRoSessionListener listener = null; protected static final String TCC_TIMER_NAME = "TCC_RoSERVER_TIMER"; protected long[] authAppIds = new long[] { 4 }; //protected String originHost, originRealm; protected IServerRoSessionData sessionData; public ServerRoSessionImpl(IServerRoSessionData sessionData, IRoMessageFactory fct, ISessionFactory sf, ServerRoSessionListener lst, IServerRoSessionContext ctx, StateChangeListener stLst) { super(sf, sessionData); if (sessionData == null) { throw new IllegalArgumentException("SessionData can not be null"); } if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationIds() == null) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.sessionData = sessionData; this.context = ctx; this.authAppIds = fct.getApplicationIds(); this.listener = lst; this.factory = fct; super.addStateChangeNotification(stLst); } @Override public void sendCreditControlAnswer(RoCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { handleEvent(new Event(false, null, answer)); } @Override public void sendReAuthRequest(ReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SENT_RAR, request, null); } @Override public boolean isStateless() { return this.sessionData.isStateless(); } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == ServerRoSessionState.class ? (E) this.sessionData.getServerRoSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { ServerRoSessionState newState = null; ServerRoSessionState state = sessionData.getServerRoSessionState(); try { sendAndStateLock.lock(); // Can be null if there is no state transition, transition to IDLE state should terminate this app session Event localEvent = (Event) event; //Its kind of awkward, but with two state on server side its easier to go through event types? //but for sake of FSM readability Event.Type eventType = (Event.Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVED_INITIAL: listener.doCreditControlRequest(this, (RoCreditControlRequest) localEvent.getRequest()); break; case RECEIVED_EVENT: // Current State: IDLE // Event: CC event request received and successfully processed // Action: Send CC event answer // New State: IDLE listener.doCreditControlRequest(this, (RoCreditControlRequest) localEvent.getRequest()); break; case SENT_EVENT_RESPONSE: // Current State: IDLE // Event: CC event request received and successfully processed // Action: Send CC event answer // New State: IDLE // Current State: IDLE // Event: CC event request received but not successfully processed // Action: Send CC event answer with Result-Code != SUCCESS // New State: IDLE newState = ServerRoSessionState.IDLE; dispatchEvent(localEvent.getAnswer()); setState(newState); break; case SENT_INITIAL_RESPONSE: RoCreditControlAnswer answer = (RoCreditControlAnswer) localEvent.getAnswer(); try { long resultCode = answer.getResultCodeAvp().getUnsigned32(); // Current State: IDLE // Event: CC initial request received and successfully processed // Action: Send CC initial answer, reserve units, start Tcc // New State: OPEN if (isSuccess(resultCode)) { Avp mscc = answer.getMessage().getAvps().getAvp(Avp.MULTIPLE_SERVICES_CREDIT_CONTROL); Avp vtAvp = mscc != null ? mscc.getGrouped().getAvp(Avp.VALIDITY_TIME) : null; startTcc(vtAvp); newState = ServerRoSessionState.OPEN; } // Current State: IDLE // Event: CC initial request received but not successfully processed // Action: Send CC initial answer with Result-Code != SUCCESS // New State: IDLE else { newState = ServerRoSessionState.IDLE; } dispatchEvent(localEvent.getAnswer()); setState(newState); } catch (AvpDataException e) { throw new InternalException(e); } break; case RECEIVED_UPDATE: case RECEIVED_TERMINATE: Answer errorAnswer = ((Request) localEvent.getRequest().getMessage()) .createAnswer(ResultCode.UNKNOWN_SESSION_ID); session.send(errorAnswer); logger.debug( "Received an UPDATE or TERMINATE for a new session. Answering with 5002 (UNKNOWN_SESSION_ID) and terminating session."); // and let it throw exception anyway ... default: throw new InternalException("Wrong state: " + ServerRoSessionState.IDLE + " one event: " + eventType + " " + localEvent.getRequest() + " " + localEvent.getAnswer()); } case OPEN: switch (eventType) { /* * This should not happen, it should be silently discarded, right? * case RECEIVED_INITIAL: * // only for rtr * if (((RoRequest) localEvent.getRequest()).getMessage().isReTransmitted()) { * listener.doCreditControlRequest(this, (RoRequest) localEvent.getRequest()); * } * else { * //do nothing? * } * break; */ case RECEIVED_UPDATE: listener.doCreditControlRequest(this, (RoCreditControlRequest) localEvent.getRequest()); break; case SENT_UPDATE_RESPONSE: RoCreditControlAnswer answer = (RoCreditControlAnswer) localEvent.getAnswer(); try { if (isSuccess(answer.getResultCodeAvp().getUnsigned32())) { // Current State: OPEN // Event: CC update request received and successfully processed // Action: Send CC update answer, debit used units, reserve new units, restart Tcc // New State: OPEN Avp mscc = answer.getMessage().getAvps().getAvp(Avp.MULTIPLE_SERVICES_CREDIT_CONTROL); Avp vtAvp = mscc != null ? mscc.getGrouped().getAvp(Avp.VALIDITY_TIME) : null; startTcc(vtAvp); } else { // Current State: OPEN // Event: CC update request received but not successfully processed // Action: Send CC update answer with Result-Code != SUCCESS, debit used units // New State: IDLE // It's a failure, we wait for Tcc to fire -- FIXME: Alexandre: Should we? } } catch (AvpDataException e) { throw new InternalException(e); } dispatchEvent(localEvent.getAnswer()); break; case RECEIVED_TERMINATE: listener.doCreditControlRequest(this, (RoCreditControlRequest) localEvent.getRequest()); break; case SENT_TERMINATE_RESPONSE: answer = (RoCreditControlAnswer) localEvent.getAnswer(); try { // Current State: OPEN // Event: CC termination request received and successfully processed // Action: Send CC termination answer, Stop Tcc, debit used units // New State: IDLE if (isSuccess(answer.getResultCodeAvp().getUnsigned32())) { stopTcc(false); } else { // Current State: OPEN // Event: CC termination request received but not successfully processed // Action: Send CC termination answer with Result-Code != SUCCESS, debit used units // New State: IDLE // It's a failure, we wait for Tcc to fire -- FIXME: Alexandre: Should we? } } catch (AvpDataException e) { throw new InternalException(e); } newState = ServerRoSessionState.IDLE; dispatchEvent(localEvent.getAnswer()); setState(newState); break; case RECEIVED_RAA: listener.doReAuthAnswer(this, new ReAuthRequestImpl(localEvent.getRequest().getMessage()), new ReAuthAnswerImpl((Answer) localEvent.getAnswer().getMessage())); break; case SENT_RAR: dispatchEvent(localEvent.getRequest()); break; } } return true; } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } private class TccScheduledTask implements Runnable { ServerRoSession session = null; private TccScheduledTask(ServerRoSession session) { super(); this.session = session; } @Override public void run() { // Current State: OPEN // Event: Session supervision timer Tcc expired // Action: Release reserved units // New State: IDLE try { sendAndStateLock.lock(); if (context != null) { context.sessionSupervisionTimerExpired(session); } } finally { try { sessionData.setTccTimerId(null); setState(ServerRoSessionState.IDLE); } catch (Exception e) { logger.error("", e); } sendAndStateLock.unlock(); } } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); //rd.session = (ServerRoSession) LocalDataSource.INSTANCE.getSession(request.getSessionId()); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } @Override public void timeoutExpired(Request request) { context.timeoutExpired(request); //FIXME: Should we release ? } private void startTcc(Avp validityAvp) { long tccTimeout; if (validityAvp != null) { try { tccTimeout = 2 * validityAvp.getUnsigned32(); } catch (AvpDataException e) { logger.debug("Unable to retrieve Validity-Time AVP value, using default.", e); tccTimeout = 2 * context.getDefaultValidityTime(); } } else { tccTimeout = 2 * context.getDefaultValidityTime(); } logger.debug("Starting TCC timer with Validity-Avp[{}] and tccTimeout[{}] seconds", validityAvp, tccTimeout); if (sessionData.getTccTimerId() != null) { stopTcc(true); //tccFuture = super.scheduler.schedule(new TccScheduledTask(this), defaultValue, TimeUnit.SECONDS); this.sessionData .setTccTimerId(super.timerFacility.schedule(this.getSessionId(), TCC_TIMER_NAME, tccTimeout * 1000)); // FIXME: this accepts Future! context.sessionSupervisionTimerReStarted(this, null); } else { //tccFuture = super.scheduler.schedule(new TccScheduledTask(this), defaultValue, TimeUnit.SECONDS); this.sessionData .setTccTimerId(super.timerFacility.schedule(this.getSessionId(), TCC_TIMER_NAME, tccTimeout * 1000)); //FIXME: this accepts Future! context.sessionSupervisionTimerStarted(this, null); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(TCC_TIMER_NAME)) { new TccScheduledTask(this).run(); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } private void stopTcc(boolean willRestart) { Serializable tccTimerId = this.sessionData.getTccTimerId(); if (tccTimerId != null) { // tccFuture.cancel(false); super.timerFacility.cancel(tccTimerId); // ScheduledFuture f = tccFuture; this.sessionData.setTccTimerId(null); if (!willRestart) { context.sessionSupervisionTimerStopped(this, null); } } } protected boolean isProvisional(long resultCode) { return resultCode >= 1000 && resultCode < 2000; } protected boolean isSuccess(long resultCode) { return resultCode >= 2000 && resultCode < 3000; } protected void setState(ServerRoSessionState newState) { setState(newState, true); } @SuppressWarnings("unchecked") protected void setState(ServerRoSessionState newState, boolean release) { IAppSessionState oldState = sessionData.getServerRoSessionState(); sessionData.setServerRoSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == ServerRoSessionState.IDLE) { stopTcc(false); if (release) { this.release(); } } } @Override public void release() { if (isValid()) { try { this.sendAndStateLock.lock(); this.stopTcc(false); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void send(Event.Type type, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { try { sendAndStateLock.lock(); if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } protected void dispatchEvent(AppEvent event) throws InternalException { try { session.send(event.getMessage(), this); } catch (Exception e) { //throw new InternalException(e); logger.debug("Failure trying to dispatch event", e); } } private class RequestDelivery implements Runnable { ServerRoSession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case RoCreditControlAnswer.code: handleEvent(new Event(true, factory.createCreditControlRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerRoSession session; Answer answer; Request request; @Override public void run() { try { // FIXME: baranowb: add message validation here!!! // We handle CCR, STR, ACR, ASR other go into extension switch (request.getCommandCode()) { case ReAuthRequest.code: handleEvent(new Event(Event.Type.RECEIVED_RAA, factory.createReAuthRequest(request), factory.createReAuthAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/rx/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.rx; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.rx.events.RxAAAnswer; import org.jdiameter.api.rx.events.RxAARequest; import org.jdiameter.api.rx.events.RxAbortSessionAnswer; import org.jdiameter.api.rx.events.RxAbortSessionRequest; import org.jdiameter.api.rx.events.RxReAuthAnswer; import org.jdiameter.api.rx.events.RxReAuthRequest; import org.jdiameter.api.rx.events.RxSessionTermAnswer; import org.jdiameter.api.rx.events.RxSessionTermRequest; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { public enum Type { SEND_AAA, RECEIVE_AAR, SEND_STA, RECEIVE_STR, SEND_RAR, RECEIVE_RAA, SEND_ASR, RECEIVE_ASA, SEND_EVENT_ANSWER, RECEIVE_EVENT_REQUEST; } Type type; AppRequestEvent request; AppAnswerEvent answer; Event(Type type) { this.type = type; } Event(Type type, AppRequestEvent request, AppAnswerEvent answer) { this.type = type; this.answer = answer; this.request = request; } Event(boolean isRequest, AppRequestEvent request, AppAnswerEvent answer) { this.answer = answer; this.request = request; if (isRequest) { switch (request.getCommandCode()) { case RxReAuthRequest.code: type = Type.SEND_RAR; break; case RxAbortSessionRequest.code: type = Type.SEND_ASR; break; case RxAARequest.code: type = Type.RECEIVE_AAR; break; case RxSessionTermRequest.code: type = Type.RECEIVE_STR; break; case 5: //BUG FIX How do we know this is an event and not a session? Do we need to fix this? Does Rx do event? type = Type.RECEIVE_EVENT_REQUEST; break; default: throw new RuntimeException("Wrong command code value: " + request.getCommandCode()); } } else { switch (answer.getCommandCode()) { case RxAbortSessionAnswer.code: type = Type.RECEIVE_ASA; break; case RxReAuthAnswer.code: type = Type.RECEIVE_RAA; break; case RxAAAnswer.code: type = Type.SEND_AAA; break; case RxSessionTermAnswer.code: type = Type.SEND_STA; break; case 6: //BUG FIX How do we know this is an event and not a session? Do we need to fix this? Does Rx do event? type = Type.SEND_EVENT_ANSWER; break; default: throw new RuntimeException("Wrong CC-Request-Type value: " + answer.getCommandCode()); } } } @Override public E encodeType(Class eClass) { return eClass == Event.Type.class ? (E) type : null; } @Override public Enum getType() { return type; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return this.request != null ? this.request : this.answer; } @Override public void setData(Object data) { // data = (AppEvent) o; // FIXME: What should we do here?! Is it request or answer? } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/rx/IServerRxSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.rx; import org.jdiameter.common.api.app.rx.IRxSessionData; import org.jdiameter.common.api.app.rx.ServerRxSessionState; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public interface IServerRxSessionData extends IRxSessionData { boolean isStateless(); void setStateless(boolean stateless); ServerRxSessionState getServerRxSessionState(); void setServerRxSessionState(ServerRxSessionState state); } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/rx/ServerRxSessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.rx; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; import org.jdiameter.common.api.app.rx.ServerRxSessionState; /** * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ServerRxSessionDataLocalImpl extends AppSessionDataLocalImpl implements IServerRxSessionData { protected boolean stateless = true; protected ServerRxSessionState state = ServerRxSessionState.IDLE; /** * */ public ServerRxSessionDataLocalImpl() { } @Override public boolean isStateless() { return stateless; } @Override public void setStateless(boolean stateless) { this.stateless = stateless; } @Override public ServerRxSessionState getServerRxSessionState() { return state; } @Override public void setServerRxSessionState(ServerRxSessionState state) { this.state = state; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/rx/ServerRxSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.rx; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.Answer; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.rx.ServerRxSession; import org.jdiameter.api.rx.ServerRxSessionListener; import org.jdiameter.api.rx.events.RxAAAnswer; import org.jdiameter.api.rx.events.RxAARequest; import org.jdiameter.api.rx.events.RxAbortSessionAnswer; import org.jdiameter.api.rx.events.RxAbortSessionRequest; import org.jdiameter.api.rx.events.RxReAuthAnswer; import org.jdiameter.api.rx.events.RxReAuthRequest; import org.jdiameter.api.rx.events.RxSessionTermAnswer; import org.jdiameter.api.rx.events.RxSessionTermRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionState; import org.jdiameter.common.api.app.rx.IRxMessageFactory; import org.jdiameter.common.api.app.rx.IServerRxSessionContext; import org.jdiameter.common.api.app.rx.ServerRxSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.rx.AppRxSessionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 3GPP IMS Rx Reference Point Server session implementation * * @author Richard Good * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ServerRxSessionImpl extends AppRxSessionImpl implements ServerRxSession, NetworkReqListener, EventListener { private static final Logger logger = LoggerFactory.getLogger(ServerRxSessionImpl.class); // Session State Handling --------------------------------------------------- //protected boolean stateless = true; //protected ServerGxSessionState state = ServerGxSessionState.IDLE; protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IRxMessageFactory factory = null; protected transient IServerRxSessionContext context = null; protected transient ServerRxSessionListener listener = null; protected long[] authAppIds = new long[] { 4 }; //protected String originHost, originRealm; protected IServerRxSessionData sessionData; public ServerRxSessionImpl(IServerRxSessionData sessionData, IRxMessageFactory fct, ISessionFactory sf, ServerRxSessionListener lst, IServerRxSessionContext ctx, StateChangeListener stLst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationIds() == null) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } context = ctx; authAppIds = fct.getApplicationIds(); listener = lst; factory = fct; this.sessionData = sessionData; super.addStateChangeNotification(stLst); } @Override public void sendAAAnswer(RxAAAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { handleEvent(new Event(false, null, answer)); } @Override public void sendSessionTermAnswer(RxSessionTermAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { handleEvent(new Event(false, null, answer)); } @Override public void sendReAuthRequest(RxReAuthRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_RAR, request, null); } @Override public void sendAbortSessionRequest(RxAbortSessionRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_ASR, request, null); } @Override public boolean isStateless() { return this.sessionData.isStateless(); } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == ServerRxSessionState.class ? (E) this.sessionData.getServerRxSessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { ServerRxSessionState newState = null; try { sendAndStateLock.lock(); // Can be null if there is no state transition, transition to IDLE state should terminate this app session final Event localEvent = (Event) event; final ServerRxSessionState state = this.sessionData.getServerRxSessionState(); //Its kind of awkward, but with two state on server side its easier to go through event types? //but for sake of FSM readability final Event.Type eventType = (Event.Type) localEvent.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVE_AAR: listener.doAARequest(this, (RxAARequest) localEvent.getRequest()); break; case RECEIVE_EVENT_REQUEST: // Current State: IDLE // Event: AA event request received and successfully processed // Action: Send AA event answer // New State: IDLE listener.doAARequest(this, (RxAARequest) localEvent.getRequest()); break; // case SEND_EVENT_ANSWER: // // Current State: IDLE // // Event: AAR event request received and successfully processed // // Action: Send AA event answer // // New State: IDLE // // newState = ServerRxSessionState.IDLE; // dispatchEvent(localEvent.getAnswer()); // break; case SEND_AAA: RxAAAnswer answer = (RxAAAnswer) localEvent.getAnswer(); try { long resultCode = answer.getResultCodeAvp().getUnsigned32(); // Current State: IDLE // Event: AA initial request received and successfully processed // Action: Send AAinitial answer // New State: OPEN if (isSuccess(resultCode)) { newState = ServerRxSessionState.OPEN; } // Current State: IDLE // Event: AA initial request received but not successfully processed // Action: Send AA initial answer with Result-Code != SUCCESS // New State: IDLE else { newState = ServerRxSessionState.IDLE; } dispatchEvent(localEvent.getAnswer()); } catch (AvpDataException e) { throw new InternalException(e); } break; default: throw new InternalException("Wrong state: " + ServerRxSessionState.IDLE + " one event: " + eventType + " " + localEvent.getRequest() + " " + localEvent.getAnswer()); } //end switch eventType break; case OPEN: switch (eventType) { case RECEIVE_AAR: listener.doAARequest(this, (RxAARequest) localEvent.getRequest()); break; case SEND_AAA: RxAAAnswer answer = (RxAAAnswer) localEvent.getAnswer(); try { if (isSuccess(answer.getResultCodeAvp().getUnsigned32())) { // Current State: OPEN // Event: AA update request received and successfully processed // Action: Send AA update answer // New State: OPEN } else { // Current State: OPEN // Event: AA update request received but not successfully processed // Action: Send AA update answer with Result-Code != SUCCESS // New State: IDLE // It's a failure, we wait for Tcc to fire -- FIXME: Alexandre: Should we? newState = ServerRxSessionState.IDLE; } } catch (AvpDataException e) { throw new InternalException(e); } dispatchEvent(localEvent.getAnswer()); break; case RECEIVE_STR: listener.doSessionTermRequest(this, (RxSessionTermRequest) localEvent.getRequest()); break; case SEND_STA: RxSessionTermAnswer STA = (RxSessionTermAnswer) localEvent.getAnswer(); try { if (isSuccess(STA.getResultCodeAvp().getUnsigned32())) { // Current State: OPEN // Event: AA update request received and successfully processed // Action: Send AA update answer // New State: OPEN } else { // Current State: OPEN // Event: AA update request received but not successfully processed // Action: Send AA update answer with Result-Code != SUCCESS // New State: IDLE // It's a failure, we wait for Tcc to fire -- FIXME: Alexandre: Should we? newState = ServerRxSessionState.IDLE; } } catch (AvpDataException e) { throw new InternalException(e); } finally { newState = ServerRxSessionState.IDLE; } dispatchEvent(localEvent.getAnswer()); break; case RECEIVE_RAA: listener.doReAuthAnswer(this, (RxReAuthRequest) localEvent.getRequest(), (RxReAuthAnswer) localEvent.getAnswer()); break; case SEND_RAR: dispatchEvent(localEvent.getRequest()); break; case RECEIVE_ASA: listener.doAbortSessionAnswer(this, (RxAbortSessionRequest) localEvent.getRequest(), (RxAbortSessionAnswer) localEvent.getAnswer()); break; case SEND_ASR: dispatchEvent(localEvent.getRequest()); break; } //end switch eventtype break; } return true; } catch (Exception e) { throw new InternalException(e); } finally { if (newState != null) { setState(newState); } sendAndStateLock.unlock(); } } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); //rd.session = (ServerRxSession) LocalDataSource.INSTANCE.getSession(request.getSessionId()); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String) */ @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } @Override public void timeoutExpired(Request request) { // context.timeoutExpired(request); //FIXME: Should we release ? } protected boolean isProvisional(long resultCode) { return resultCode >= 1000 && resultCode < 2000; } protected boolean isSuccess(long resultCode) { return resultCode >= 2000 && resultCode < 3000; } protected void setState(ServerRxSessionState newState) { setState(newState, true); } @SuppressWarnings("unchecked") protected void setState(ServerRxSessionState newState, boolean release) { IAppSessionState oldState = this.sessionData.getServerRxSessionState(); this.sessionData.setServerRxSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, (Enum) oldState, (Enum) newState); } if (newState == ServerRxSessionState.IDLE) { if (release) { // NOTE: do EVERYTHING before release. this.release(); } } } @Override public void release() { if (isValid()) { try { this.sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected void send(Event.Type type, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { try { sendAndStateLock.lock(); if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } } protected void dispatchEvent(AppEvent event) throws InternalException { try { session.send(event.getMessage(), this); // Store last destination information } catch (Exception e) { //throw new InternalException(e); logger.debug("Failure trying to dispatch event", e); } } private class RequestDelivery implements Runnable { ServerRxSession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case RxAARequest.code: handleEvent(new Event(true, factory.createAARequest(request), null)); break; case RxSessionTermRequest.code: handleEvent(new Event(true, factory.createSessionTermRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerRxSession session; Answer answer; Request request; @Override public void run() { try { // FIXME: baranowb: add message validation here!!! // We handle CCR, STR, ACR, ASR other go into extension switch (request.getCommandCode()) { case RxReAuthRequest.code: handleEvent(new Event(Event.Type.RECEIVE_RAA, factory.createReAuthRequest(request), factory.createReAuthAnswer(answer))); break; case RxAbortSessionRequest.code: handleEvent(new Event(Event.Type.RECEIVE_ASA, factory.createAbortSessionRequest(request), factory.createAbortSessionAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } ServerRxSessionImpl other = (ServerRxSessionImpl) obj; if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/s13/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.server.impl.app.s13; import org.jdiameter.api.InternalException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_ECR, } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { try { if (((AppEvent) data).getMessage().isRequest()) { request = (AppEvent) data; } else { answer = (AppEvent) data; } } catch (InternalException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/s13/IServerS13SessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.server.impl.app.s13; import org.jdiameter.common.api.app.s13.IS13SessionData; @SuppressWarnings("all") //3rd party lib public interface IServerS13SessionData extends IS13SessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/s13/S13ServerSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.server.impl.app.s13; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.s13.ServerS13Session; import org.jdiameter.api.s13.ServerS13SessionListener; import org.jdiameter.api.s13.events.JMEIdentityCheckAnswer; import org.jdiameter.api.s13.events.JMEIdentityCheckRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.s13.IS13MessageFactory; import org.jdiameter.common.api.app.s13.S13SessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.s13.S13Session; import org.jdiameter.server.impl.app.s13.Event.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SuppressWarnings("all") //3rd party lib public class S13ServerSessionImpl extends S13Session implements ServerS13Session, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(S13ServerSessionImpl.class); // Factories and Listeners // -------------------------------------------------- private transient ServerS13SessionListener listener; protected long appId = -1; protected IServerS13SessionData sessionData; public S13ServerSessionImpl(IServerS13SessionData sessionData, IS13MessageFactory fct, ISessionFactory sf, ServerS13SessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if ((this.appId = fct.getApplicationId()) < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } @Override public void sendMEIdentityCheckAnswer(JMEIdentityCheckAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == S13SessionState.class ? (E) this.sessionData.getS13SessionState() : null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final S13SessionState state = this.sessionData.getS13SessionState(); S13SessionState newState = null; Event localEvent = (Event) event; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVE_ECR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = S13SessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doMEIdentityCheckRequestEvent(this, (JMEIdentityCheckRequest) event.getData()); break; case SEND_MESSAGE: super.session.send(((AppEvent) event.getData()).getMessage(), this); newState = S13SessionState.MESSAGE_SENT_RECEIVED; setState(newState); break; default: logger.error("Wrong action in S13 Server FSM. State: IDLE, Event Type: {}", eventType); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = S13SessionState.TIMEDOUT; setState(newState); break; case SEND_MESSAGE: try { super.session.send(((AppEvent) event.getData()).getMessage(), this); } finally { newState = S13SessionState.TERMINATED; setState(newState); } break; default: throw new InternalException( "Should not receive more messages after initial. Command: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("S13 Server FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } @Override public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } @SuppressWarnings("unchecked") protected void setState(S13SessionState newState) { S13SessionState oldState = this.sessionData.getS13SessionState(); this.sessionData.setS13SessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == S13SessionState.TERMINATED || newState == S13SessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); } } @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(S13Session.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ServerS13Session session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case JMEIdentityCheckRequest.code: handleEvent( new Event(Event.Type.RECEIVE_ECR, messageFactory.createMEIdentityCheckRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerS13Session session; Answer answer; Request request; @Override public void run() { try { switch (answer.getCommandCode()) { default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/s13/ServerS13SessionDataLocalImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.server.impl.app.s13; import org.jdiameter.common.impl.app.s13.S13LocalSessionDataImpl; @SuppressWarnings("all") //3rd party lib public class ServerS13SessionDataLocalImpl extends S13LocalSessionDataImpl implements IServerS13SessionData { public ServerS13SessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/s6a/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.s6a; import org.jdiameter.api.InternalException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_AIR, RECEIVE_PUR, RECEIVE_ULR, RECEIVE_NOR, RECEIVE_CLA, RECEIVE_IDA, RECEIVE_DSA, RECEIVE_RSA; } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { try { if (((AppEvent) data).getMessage().isRequest()) { request = (AppEvent) data; } else { answer = (AppEvent) data; } } catch (InternalException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/s6a/IServerS6aSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.s6a; import org.jdiameter.common.api.app.s6a.IS6aSessionData; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public interface IServerS6aSessionData extends IS6aSessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/s6a/S6aServerSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.s6a; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.s6a.ServerS6aSession; import org.jdiameter.api.s6a.ServerS6aSessionListener; import org.jdiameter.api.s6a.events.*; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.s6a.IS6aMessageFactory; import org.jdiameter.common.api.app.s6a.S6aSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.s6a.S6aSession; import org.jdiameter.server.impl.app.s6a.Event.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * S6a Server session implementation * * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class S6aServerSessionImpl extends S6aSession implements ServerS6aSession, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(S6aServerSessionImpl.class); // Factories and Listeners -------------------------------------------------- private transient ServerS6aSessionListener listener; protected long appId = -1; protected IServerS6aSessionData sessionData; public S6aServerSessionImpl(IServerS6aSessionData sessionData, IS6aMessageFactory fct, ISessionFactory sf, ServerS6aSessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if ((this.appId = fct.getApplicationId()) < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } @Override public void sendAuthenticationInformationAnswer(JAuthenticationInformationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } @Override public void sendPurgeUEAnswer(JPurgeUEAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } @Override public void sendUpdateLocationAnswer(JUpdateLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } @Override public void sendNotifyAnswer(JNotifyAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } @Override public void sendCancelLocationRequest(JCancelLocationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } @Override public void sendInsertSubscriberDataRequest(JInsertSubscriberDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } @Override public void sendDeleteSubscriberDataRequest(JDeleteSubscriberDataRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } @Override public void sendResetRequest(JResetRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateMachine#getState(java.lang.Class) */ @Override @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == S6aSessionState.class ? (E) this.sessionData.getS6aSessionState() : null; } /* * (non-Javadoc) * * @see org.jdiameter.api.app.StateMachine#handleEvent(org.jdiameter.api.app.StateEvent) */ @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final S6aSessionState state = this.sessionData.getS6aSessionState(); S6aSessionState newState = null; Event localEvent = (Event) event; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVE_AIR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = S6aSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doAuthenticationInformationRequestEvent(this, (JAuthenticationInformationRequest) event.getData()); break; case RECEIVE_PUR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = S6aSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doPurgeUERequestEvent(this, (JPurgeUERequest) event.getData()); break; case RECEIVE_ULR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = S6aSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doUpdateLocationRequestEvent(this, (JUpdateLocationRequest) event.getData()); break; case RECEIVE_NOR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = S6aSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doNotifyRequestEvent(this, (JNotifyRequest) event.getData()); break; case SEND_MESSAGE: super.session.send(((AppEvent) event.getData()).getMessage(), this); newState = S6aSessionState.MESSAGE_SENT_RECEIVED; setState(newState); break; default: logger.error("Wrong action in S6a Server FSM. State: IDLE, Event Type: {}", eventType); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = S6aSessionState.TIMEDOUT; setState(newState); break; case SEND_MESSAGE: try { super.session.send(((AppEvent) event.getData()).getMessage(), this); } finally { newState = S6aSessionState.TERMINATED; setState(newState); } break; case RECEIVE_CLA: try { super.cancelMsgTimer(); listener.doCancelLocationAnswerEvent(this, (JCancelLocationRequest) localEvent.getRequest(), (JCancelLocationAnswer) localEvent.getAnswer()); } finally { newState = S6aSessionState.TERMINATED; setState(newState); } break; case RECEIVE_IDA: try { super.cancelMsgTimer(); listener.doInsertSubscriberDataAnswerEvent(this, (JInsertSubscriberDataRequest) localEvent.getRequest(), (JInsertSubscriberDataAnswer) localEvent.getAnswer()); } finally { newState = S6aSessionState.TERMINATED; setState(newState); } break; case RECEIVE_DSA: try { super.cancelMsgTimer(); listener.doDeleteSubscriberDataAnswerEvent(this, (JDeleteSubscriberDataRequest) localEvent.getRequest(), (JDeleteSubscriberDataAnswer) localEvent.getAnswer()); } finally { newState = S6aSessionState.TERMINATED; setState(newState); } break; case RECEIVE_RSA: try { super.cancelMsgTimer(); listener.doResetAnswerEvent(this, (JResetRequest) localEvent.getRequest(), (JResetAnswer) localEvent.getAnswer()); } finally { newState = S6aSessionState.TERMINATED; setState(newState); } break; default: throw new InternalException( "Should not receive more messages after initial. Command: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("S6a Server FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } /* * (non-Javadoc) * * @see org.jdiameter.api.EventListener#receivedSuccessMessage(org.jdiameter.api.Message, org.jdiameter.api.Message) */ @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } /* * (non-Javadoc) * * @see org.jdiameter.api.EventListener#timeoutExpired(org.jdiameter.api.Message) */ @Override public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } /* * (non-Javadoc) * * @see org.jdiameter.api.NetworkReqListener#processRequest(org.jdiameter.api.Request) */ @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } @SuppressWarnings("unchecked") protected void setState(S6aSessionState newState) { S6aSessionState oldState = this.sessionData.getS6aSessionState(); this.sessionData.setS6aSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == S6aSessionState.TERMINATED || newState == S6aSessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); } } @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else if (timerName.equals(S6aSession.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ServerS6aSession session; Request request; @Override public void run() { try { switch (request.getCommandCode()) { case JAuthenticationInformationRequest.code: handleEvent(new Event(Event.Type.RECEIVE_AIR, messageFactory.createAuthenticationInformationRequest(request), null)); break; case JPurgeUERequest.code: handleEvent(new Event(Event.Type.RECEIVE_PUR, messageFactory.createPurgeUERequest(request), null)); break; case JUpdateLocationRequest.code: handleEvent( new Event(Event.Type.RECEIVE_ULR, messageFactory.createUpdateLocationRequest(request), null)); break; case JNotifyRequest.code: handleEvent(new Event(Event.Type.RECEIVE_NOR, messageFactory.createNotifyRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerS6aSession session; Answer answer; Request request; @Override public void run() { try { switch (answer.getCommandCode()) { case JCancelLocationAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_CLA, messageFactory.createCancelLocationRequest(request), messageFactory.createCancelLocationAnswer(answer))); break; case JInsertSubscriberDataAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_IDA, messageFactory.createInsertSubscriberDataRequest(request), messageFactory.createInsertSubscriberDataAnswer(answer))); break; case JDeleteSubscriberDataAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_DSA, messageFactory.createDeleteSubscriberDataRequest(request), messageFactory.createDeleteSubscriberDataAnswer(answer))); break; case JResetAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_RSA, messageFactory.createResetRequest(request), messageFactory.createResetAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/s6a/ServerS6aSessionDataLocalImpl.java ================================================ /* * 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.jdiameter.server.impl.app.s6a; import org.jdiameter.common.impl.app.s6a.S6aLocalSessionDataImpl; /** * @author Alexandre Mendonca * @author Richard Good * @author Paul Carter-Brown */ @SuppressWarnings("all") //3rd party lib public class ServerS6aSessionDataLocalImpl extends S6aLocalSessionDataImpl implements IServerS6aSessionData { public ServerS6aSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/sh/Event.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.sh; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { RECEIVE_USER_DATA_REQUEST, RECEIVE_PROFILE_UPDATE_REQUEST, RECEIVE_SUBSCRIBE_NOTIFICATIONS_REQUEST, RECEIVE_PUSH_NOTIFICATION_ANSWER, SEND_PUSH_NOTIFICATION_REQUEST, SEND_USER_DATA_ANSWER, SEND_PROFILE_UPDATE_ANSWER, SEND_SUBSCRIBE_NOTIFICATIONS_ANSWER, TIMEOUT_EXPIRES, //Add this to allow app to respond, and in case of app error not to leave it behind TX_TIMER_EXPIRED; } Type type; AppEvent request; AppEvent answer; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @Override public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @Override public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } @Override public int compareTo(Object o) { return 0; } @Override public Object getData() { return request != null ? request : answer; } @Override public void setData(Object data) { // FIXME: What should we do here?! Is it request or answer? } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/sh/IShServerSessionData.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.sh; import org.jdiameter.common.api.app.sh.IShSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public interface IShServerSessionData extends IShSessionData { // stateless } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/sh/ShServerSessionDataLocalImpl.java ================================================ /* * JBoss, Home of Professional Open Source * Copyright 2008, 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.jdiameter.server.impl.app.sh; import org.jdiameter.common.api.app.AppSessionDataLocalImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ShServerSessionDataLocalImpl extends AppSessionDataLocalImpl implements IShServerSessionData { public ShServerSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/sh/ShServerSessionImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.app.sh; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.jdiameter.api.Answer; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.sh.ServerShSession; import org.jdiameter.api.sh.ServerShSessionListener; import org.jdiameter.api.sh.events.ProfileUpdateAnswer; import org.jdiameter.api.sh.events.ProfileUpdateRequest; import org.jdiameter.api.sh.events.PushNotificationAnswer; import org.jdiameter.api.sh.events.PushNotificationRequest; import org.jdiameter.api.sh.events.SubscribeNotificationsAnswer; import org.jdiameter.api.sh.events.SubscribeNotificationsRequest; import org.jdiameter.api.sh.events.UserDataAnswer; import org.jdiameter.api.sh.events.UserDataRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.sh.IShMessageFactory; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.sh.ShSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Basic implementation of ShServerSession - can be one time - for UDR, PUR and constant for SNR-PNR pair, in case when * SNA contains response code from range different than 2001-2004(success codes) user is responsible for maintaing state * - releasing etc, same goes if result code is contained Experimental-Result AVP
      * If ShSession moves to * ShSessionState.TERMINATED - it means that no further messages can be received via it and it should be discarded. *
      *
      * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class ShServerSessionImpl extends ShSession implements ServerShSession, EventListener, NetworkReqListener { private Logger logger = LoggerFactory.getLogger(ShServerSessionImpl.class); // Session State Handling --------------------------------------------------- protected Lock sendAndStateLock = new ReentrantLock(); // Factories and Listeners -------------------------------------------------- protected transient IShMessageFactory factory = null; protected transient ServerShSessionListener listener; protected IShServerSessionData sessionData; protected long appId; public ShServerSessionImpl(IShServerSessionData sessionData, IShMessageFactory fct, ISessionFactory sf, ServerShSessionListener lst) { super(sf, sessionData); if (sessionData == null) { throw new NullPointerException("SessionData must not be null"); } if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if (fct.getApplicationId() < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.sessionData = sessionData; this.appId = fct.getApplicationId(); this.listener = lst; this.factory = fct; } @Override public void sendProfileUpdateAnswer(ProfileUpdateAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_PROFILE_UPDATE_ANSWER, null, answer); } @Override public void sendPushNotificationRequest(PushNotificationRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_PUSH_NOTIFICATION_REQUEST, request, null); } @Override public void sendSubscribeNotificationsAnswer(SubscribeNotificationsAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_SUBSCRIBE_NOTIFICATIONS_ANSWER, null, answer); } @Override public void sendUserDataAnswer(UserDataAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_USER_DATA_ANSWER, null, answer); } @Override public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } @Override public void timeoutExpired(Request request) { try { sendAndStateLock.lock(); if (request.getApplicationId() == appId) { if (request.getCommandCode() == PushNotificationRequest.code) { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, factory.createPushNotificationRequest(request), null)); return; } } } catch (Exception e) { logger.debug("Failed to process timeout message", e); } finally { sendAndStateLock.unlock(); } } @Override public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } @Override public E getState(Class stateType) { return null; } @Override public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); Event localEvent = (Event) event; switch ((Event.Type) localEvent.getType()) { case RECEIVE_PROFILE_UPDATE_REQUEST: listener.doProfileUpdateRequestEvent(this, (ProfileUpdateRequest) localEvent.getRequest()); break; case RECEIVE_PUSH_NOTIFICATION_ANSWER: listener.doPushNotificationAnswerEvent(this, (PushNotificationRequest) localEvent.getRequest(), (PushNotificationAnswer) localEvent.getAnswer()); break; case RECEIVE_SUBSCRIBE_NOTIFICATIONS_REQUEST: listener.doSubscribeNotificationsRequestEvent(this, (SubscribeNotificationsRequest) localEvent.getRequest()); break; case RECEIVE_USER_DATA_REQUEST: listener.doUserDataRequestEvent(this, (UserDataRequest) localEvent.getRequest()); break; case SEND_PROFILE_UPDATE_ANSWER: dispatchEvent(localEvent.getAnswer()); break; case SEND_PUSH_NOTIFICATION_REQUEST: dispatchEvent(localEvent.getRequest()); break; case SEND_SUBSCRIBE_NOTIFICATIONS_ANSWER: dispatchEvent(localEvent.getAnswer()); break; case SEND_USER_DATA_ANSWER: dispatchEvent(localEvent.getAnswer()); break; case TIMEOUT_EXPIRES: break; default: logger.error("Wrong message type = {} req = {} ans = {}", new Object[] { localEvent.getType(), localEvent.getRequest(), localEvent.getAnswer() }); } } catch (IllegalDiameterStateException idse) { throw new InternalException(idse); } catch (RouteException re) { throw new InternalException(re); } finally { sendAndStateLock.unlock(); } return true; } @Override public boolean isStateless() { return true; } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { //FIXME: isnt this bad? Shouldnt send be before state change? sendAndStateLock.lock(); if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception exc) { throw new InternalException(exc); } finally { sendAndStateLock.unlock(); } } protected void dispatchEvent(AppEvent event) throws InternalException { try { session.send(event.getMessage(), this); // FIXME: add differentiation on server/client request } catch (Exception e) { logger.debug("Failed to dispatch event", e); } } @Override public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } protected long extractExpiryTime(Message answer) { try { // FIXME: Replace 709 by Avp.EXPIRY_TIME Avp expiryTimeAvp = answer.getAvps().getAvp(709); return expiryTimeAvp != null ? expiryTimeAvp.getTime().getTime() : -1; } catch (AvpDataException ade) { logger.debug("Failure trying to extract Expiry-Time AVP value", ade); } return -1; } /* * (non-Javadoc) * * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable() */ @Override public boolean isReplicable() { return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (appId ^ (appId >>> 32)); result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ShServerSessionImpl other = (ShServerSessionImpl) obj; if (appId != other.appId) { return false; } if (sessionData == null) { if (other.sessionData != null) { return false; } } else if (!sessionData.equals(other.sessionData)) { return false; } return true; } @Override public void onTimer(String timerName) { if (timerName.equals(IDLE_SESSION_TIMER_NAME)) { checkIdleAppSession(); } else { logger.warn("Received an unknown timer '{}' for Session-ID '{}'", timerName, getSessionId()); } } private class RequestDelivery implements Runnable { ServerShSession session; Request request; @Override public void run() { try { if (request.getApplicationId() == appId) { if (request.getCommandCode() == SubscribeNotificationsRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_SUBSCRIBE_NOTIFICATIONS_REQUEST, factory.createSubscribeNotificationsRequest(request), null)); } else if (request.getCommandCode() == UserDataRequest.code) { handleEvent( new Event(Event.Type.RECEIVE_USER_DATA_REQUEST, factory.createUserDataRequest(request), null)); } else if (request.getCommandCode() == ProfileUpdateRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_PROFILE_UPDATE_REQUEST, factory.createProfileUpdateRequest(request), null)); } else { listener.doOtherEvent(session, new AppRequestEventImpl(request), null); } } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerShSession session; Answer answer; Request request; @Override public void run() { try { sendAndStateLock.lock(); if (request.getApplicationId() == appId) { if (request.getCommandCode() == PushNotificationRequest.code) { handleEvent(new Event(Event.Type.RECEIVE_PUSH_NOTIFICATION_ANSWER, factory.createPushNotificationRequest(request), factory.createPushNotificationAnswer(answer))); return; } else { listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); } } else { logger.warn("Message with Application-Id {} reached Application Session with Application-Id {}. Skipping.", request.getApplicationId(), appId); } } catch (Exception e) { logger.debug("Failed to process success message", e); } finally { sendAndStateLock.unlock(); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/Event.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.server.impl.app.slg; import org.jdiameter.api.InternalException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_PLR, RECEIVE_LRA } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @SuppressWarnings("unchecked") public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @SuppressWarnings("rawtypes") public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } public int compareTo(Object o) { return 0; } public Object getData() { return request != null ? request : answer; } public void setData(Object data) { try { if (((AppEvent) data).getMessage().isRequest()) { request = (AppEvent) data; } else { answer = (AppEvent) data; } } catch (InternalException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/IServerSLgSessionData.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.server.impl.app.slg; import org.jdiameter.common.api.app.slg.ISLgSessionData; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface IServerSLgSessionData extends ISLgSessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/SLgServerSessionImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.server.impl.app.slg; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.slg.ServerSLgSession; import org.jdiameter.api.slg.ServerSLgSessionListener; import org.jdiameter.api.slg.events.LocationReportAnswer; import org.jdiameter.api.slg.events.LocationReportRequest; import org.jdiameter.api.slg.events.ProvideLocationAnswer; import org.jdiameter.api.slg.events.ProvideLocationRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.slg.ISLgMessageFactory; import org.jdiameter.common.api.app.slg.SLgSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.slg.SLgSession; import org.jdiameter.server.impl.app.slg.Event.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLgServerSessionImpl extends SLgSession implements ServerSLgSession, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(SLgServerSessionImpl.class); // Factories and Listeners // -------------------------------------------------- private transient ServerSLgSessionListener listener; protected long appId = -1; protected IServerSLgSessionData sessionData; public SLgServerSessionImpl(IServerSLgSessionData sessionData, ISLgMessageFactory fct, ISessionFactory sf, ServerSLgSessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if ((this.appId = fct.getApplicationId()) < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } public void sendProvideLocationAnswer(ProvideLocationAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } public void sendLocationReportRequest(LocationReportRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, request, null); } @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == SLgSessionState.class ? (E) this.sessionData.getSLgSessionState() : null; } @SuppressWarnings("unused") public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final SLgSessionState state = this.sessionData.getSLgSessionState(); SLgSessionState newState; Event localEvent = (Event) event; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVE_PLR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = SLgSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doProvideLocationRequestEvent(this, (ProvideLocationRequest) event.getData()); break; case SEND_MESSAGE: super.session.send(((AppEvent) event.getData()).getMessage(), this); newState = SLgSessionState.MESSAGE_SENT_RECEIVED; setState(newState); break; default: logger.error("Wrong action in SLg Server FSM. State: IDLE, Event Type: {}", eventType); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = SLgSessionState.TIMEDOUT; setState(newState); break; case RECEIVE_LRA: newState = SLgSessionState.TERMINATED; setState(newState); listener.doLocationReportAnswerEvent(this, (LocationReportRequest) localEvent.getRequest(), (LocationReportAnswer) localEvent.getAnswer()); break; case SEND_MESSAGE: try { super.session.send(((AppEvent) event.getData()).getMessage(), this); } finally { newState = SLgSessionState.TERMINATED; setState(newState); } break; default: throw new InternalException( "Should not receive more messages after initial. Command: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("SLg Server FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } @SuppressWarnings({ "unchecked", "rawtypes" }) protected void setState(SLgSessionState newState) { SLgSessionState oldState = this.sessionData.getSLgSessionState(); this.sessionData.setSLgSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == SLgSessionState.TERMINATED || newState == SLgSessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); } } @Override public void onTimer(String timerName) { if (timerName.equals(SLgSession.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } } public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ServerSLgSession session; Request request; public void run() { try { switch (request.getCommandCode()) { case ProvideLocationRequest.code: handleEvent( new Event(Event.Type.RECEIVE_PLR, messageFactory.createProvideLocationRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerSLgSession session; Answer answer; Request request; public void run() { try { switch (answer.getCommandCode()) { case LocationReportAnswer.code: handleEvent(new Event(Event.Type.RECEIVE_LRA, messageFactory.createLocationReportRequest(request), messageFactory.createLocationReportAnswer(answer))); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/ServerSLgSessionDataLocalImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.server.impl.app.slg; import org.jdiameter.common.impl.app.slg.SLgLocalSessionDataImpl; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class ServerSLgSessionDataLocalImpl extends SLgLocalSessionDataImpl implements IServerSLgSessionData { public ServerSLgSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/Event.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.server.impl.app.slh; import org.jdiameter.api.InternalException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateEvent; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class Event implements StateEvent { enum Type { SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_RIR; } AppEvent request; AppEvent answer; Type type; Event(Type type, AppEvent request, AppEvent answer) { this.type = type; this.answer = answer; this.request = request; } @SuppressWarnings("unchecked") public E encodeType(Class eClass) { return eClass == Type.class ? (E) type : null; } @SuppressWarnings("rawtypes") public Enum getType() { return type; } public AppEvent getRequest() { return request; } public AppEvent getAnswer() { return answer; } public int compareTo(Object o) { return 0; } public Object getData() { return request != null ? request : answer; } public void setData(Object data) { try { if (((AppEvent) data).getMessage().isRequest()) { request = (AppEvent) data; } else { answer = (AppEvent) data; } } catch (InternalException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/IServerSLhSessionData.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.server.impl.app.slh; import org.jdiameter.common.api.app.slh.ISLhSessionData; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public interface IServerSLhSessionData extends ISLhSessionData { } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/SLhServerSessionImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.server.impl.app.slh; import org.jdiameter.api.Answer; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.app.AppEvent; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.api.app.StateEvent; import org.jdiameter.api.slh.ServerSLhSession; import org.jdiameter.api.slh.ServerSLhSessionListener; import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.slh.ISLhMessageFactory; import org.jdiameter.common.api.app.slh.SLhSessionState; import org.jdiameter.common.impl.app.AppAnswerEventImpl; import org.jdiameter.common.impl.app.AppRequestEventImpl; import org.jdiameter.common.impl.app.slh.SLhSession; import org.jdiameter.server.impl.app.slh.Event.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class SLhServerSessionImpl extends SLhSession implements ServerSLhSession, EventListener, NetworkReqListener { private static final Logger logger = LoggerFactory.getLogger(SLhServerSessionImpl.class); // Factories and Listeners // -------------------------------------------------- private transient ServerSLhSessionListener listener; protected long appId = -1; protected IServerSLhSessionData sessionData; public SLhServerSessionImpl(IServerSLhSessionData sessionData, ISLhMessageFactory fct, ISessionFactory sf, ServerSLhSessionListener lst) { super(sf, sessionData); if (lst == null) { throw new IllegalArgumentException("Listener can not be null"); } if ((this.appId = fct.getApplicationId()) < 0) { throw new IllegalArgumentException("ApplicationId can not be less than zero"); } this.listener = lst; super.messageFactory = fct; this.sessionData = sessionData; } public void sendLCSRoutingInfoAnswer(LCSRoutingInfoAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { send(Event.Type.SEND_MESSAGE, null, answer); } @SuppressWarnings("unchecked") public E getState(Class stateType) { return stateType == SLhSessionState.class ? (E) this.sessionData.getSLhSessionState() : null; } @SuppressWarnings("unused") public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { try { sendAndStateLock.lock(); if (!super.session.isValid()) { // FIXME: throw new InternalException("Generic session is not valid."); return false; } final SLhSessionState state = this.sessionData.getSLhSessionState(); SLhSessionState newState; Event localEvent = (Event) event; Event.Type eventType = (Type) event.getType(); switch (state) { case IDLE: switch (eventType) { case RECEIVE_RIR: this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); super.cancelMsgTimer(); super.startMsgTimer(); newState = SLhSessionState.MESSAGE_SENT_RECEIVED; setState(newState); listener.doLCSRoutingInfoRequestEvent(this, (LCSRoutingInfoRequest) event.getData()); break; case SEND_MESSAGE: super.session.send(((AppEvent) event.getData()).getMessage(), this); newState = SLhSessionState.MESSAGE_SENT_RECEIVED; setState(newState); break; default: logger.error("Wrong action in SLh Server FSM. State: IDLE, Event Type: {}", eventType); break; } break; case MESSAGE_SENT_RECEIVED: switch (eventType) { case TIMEOUT_EXPIRES: newState = SLhSessionState.TIMEDOUT; setState(newState); break; case SEND_MESSAGE: try { super.session.send(((AppEvent) event.getData()).getMessage(), this); } finally { newState = SLhSessionState.TERMINATED; setState(newState); } break; default: throw new InternalException( "Should not receive more messages after initial. Command: " + event.getData()); } break; case TERMINATED: throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); case TIMEDOUT: throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); default: logger.error("SLh Server FSM in wrong state: {}", state); break; } } catch (Exception e) { throw new InternalException(e); } finally { sendAndStateLock.unlock(); } return true; } public void receivedSuccessMessage(Request request, Answer answer) { AnswerDelivery rd = new AnswerDelivery(); rd.session = this; rd.request = request; rd.answer = answer; super.scheduler.execute(rd); } public void timeoutExpired(Request request) { try { handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); } catch (Exception e) { logger.debug("Failed to process timeout message", e); } } public Answer processRequest(Request request) { RequestDelivery rd = new RequestDelivery(); rd.session = this; rd.request = request; super.scheduler.execute(rd); return null; } protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { try { if (type != null) { handleEvent(new Event(type, request, answer)); } } catch (Exception e) { throw new InternalException(e); } } @SuppressWarnings({ "unchecked", "rawtypes" }) protected void setState(SLhSessionState newState) { SLhSessionState oldState = this.sessionData.getSLhSessionState(); this.sessionData.setSLhSessionState(newState); for (StateChangeListener i : stateListeners) { i.stateChanged(this, oldState, newState); } if (newState == SLhSessionState.TERMINATED || newState == SLhSessionState.TIMEDOUT) { super.cancelMsgTimer(); this.release(); } } @Override public void onTimer(String timerName) { if (timerName.equals(SLhSession.TIMER_NAME_MSG_TIMEOUT)) { try { sendAndStateLock.lock(); try { handleEvent( new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); } catch (Exception e) { logger.debug("Failure handling Timeout event."); } this.sessionData.setBuffer(null); this.sessionData.setTsTimerId(null); } finally { sendAndStateLock.unlock(); } } } public void release() { if (isValid()) { try { sendAndStateLock.lock(); super.release(); } catch (Exception e) { logger.debug("Failed to release session", e); } finally { sendAndStateLock.unlock(); } } else { logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); } } private class RequestDelivery implements Runnable { ServerSLhSession session; Request request; public void run() { try { switch (request.getCommandCode()) { case LCSRoutingInfoRequest.code: handleEvent( new Event(Event.Type.RECEIVE_RIR, messageFactory.createLCSRoutingInfoRequest(request), null)); break; default: listener.doOtherEvent(session, new AppRequestEventImpl(request), null); break; } } catch (Exception e) { logger.debug("Failed to process request message", e); } } } private class AnswerDelivery implements Runnable { ServerSLhSession session; Answer answer; Request request; public void run() { try { switch (answer.getCommandCode()) { default: listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); break; } } catch (Exception e) { logger.debug("Failed to process success message", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/ServerSLhSessionDataLocalImpl.java ================================================ /* * * TeleStax, Open Source Cloud Communications * Copyright 2011-2017, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * */ package org.jdiameter.server.impl.app.slh; import org.jdiameter.common.impl.app.slh.SLhLocalSessionDataImpl; /** * @author Fernando Mendioroz */ @SuppressWarnings("all") //3rd party lib public class ServerSLhSessionDataLocalImpl extends SLhLocalSessionDataImpl implements IServerSLhSessionData { public ServerSLhSessionDataLocalImpl() { } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/fsm/FsmFactoryImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.fsm; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.client.api.fsm.IContext; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.server.api.IFsmFactory; import org.jdiameter.server.api.IStateMachine; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class FsmFactoryImpl extends org.jdiameter.client.impl.fsm.FsmFactoryImpl implements IFsmFactory { public FsmFactoryImpl(IStatisticManager statisticFactory) { super(statisticFactory); } @Override public IStateMachine createInstanceFsm(IContext context, IConcurrentFactory concurrentFactory, Configuration config) throws InternalException { return new org.jdiameter.server.impl.fsm.PeerFSMImpl(context, concurrentFactory, config, statisticFactory); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/fsm/PeerFSMImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.fsm; import static org.jdiameter.client.impl.fsm.FsmState.*; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Configuration; import org.jdiameter.api.ConfigurationListener; import org.jdiameter.api.DisconnectCause; import org.jdiameter.api.MutableConfiguration; import org.jdiameter.api.ResultCode; import org.jdiameter.api.app.State; import org.jdiameter.api.app.StateEvent; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.fsm.IContext; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.server.api.IStateMachine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class PeerFSMImpl extends org.jdiameter.client.impl.fsm.PeerFSMImpl implements IStateMachine, ConfigurationListener { private static final Logger logger = LoggerFactory.getLogger(org.jdiameter.server.impl.fsm.PeerFSMImpl.class); public PeerFSMImpl(IContext context, IConcurrentFactory concurrentFactory, Configuration config, IStatisticManager statisticFactory) { super(context, concurrentFactory, config, statisticFactory); } @Override protected void loadTimeOuts(Configuration config) { super.loadTimeOuts(config); if (config instanceof MutableConfiguration) { ((MutableConfiguration) config).addChangeListener(this, 0); } } @Override public boolean elementChanged(int i, Object data) { Configuration newConfig = (Configuration) data; super.loadTimeOuts(newConfig); return true; } @Override protected State[] getStates() { if (states == null) { states = new State[] { new MyState() { // OKEY @Override public void entryAction() { // todo send buffered messages setInActiveTimer(); watchdogSent = false; } @Override public boolean processEvent(StateEvent event) { switch (type(event)) { case DISCONNECT_EVENT: doEndConnection(); break; case TIMEOUT_EVENT: try { context.sendDwrMessage(); setTimer(DWA_TIMEOUT); if (watchdogSent) { switchToNextState(SUSPECT); } else { watchdogSent = true; } } catch (Throwable e) { logger.debug("Can not send DWR", e); doDisconnect(); doEndConnection(); } break; case STOP_EVENT: try { if (event.getData() == null) { context.sendDprMessage(DisconnectCause.BUSY); } else { Integer disconnectCause = (Integer) event.getData(); context.sendDprMessage(disconnectCause); } setTimer(DPA_TIMEOUT); switchToNextState(STOPPING); } catch (Throwable e) { logger.debug("Can not send DPR", e); doDisconnect(); switchToNextState(DOWN); } break; case RECEIVE_MSG_EVENT: setInActiveTimer(); context.receiveMessage(message(event)); break; case CEA_EVENT: setInActiveTimer(); if (context.processCeaMessage(key(event), message(event))) { doDisconnect(); // ! doEndConnection(); } break; case CER_EVENT: // setInActiveTimer(); logger.debug("Rejecting CER in OKAY state. Answering with UNABLE_TO_COMPLY (5012)"); try { context.sendCeaMessage(ResultCode.UNABLE_TO_COMPLY, message(event), "Unable to receive CER in OPEN state."); } catch (Exception e) { logger.debug("Failed to send CEA.", e); doDisconnect(); // ! doEndConnection(); } break; case DPR_EVENT: try { int code = context.processDprMessage((IMessage) event.getData()); context.sendDpaMessage(message(event), code, null); } catch (Throwable e) { logger.debug("Can not send DPA", e); } IMessage message = (IMessage) event.getData(); try { Avp discCause = message.getAvps().getAvp(Avp.DISCONNECT_CAUSE); boolean willReconnect = (discCause != null) ? (discCause.getInteger32() == DisconnectCause.REBOOTING) : false; if (willReconnect) { doDisconnect(); doEndConnection(); } else { doDisconnect(); switchToNextState(DOWN); } } catch (AvpDataException ade) { logger.warn("Disconnect cause is bad.", ade); doDisconnect(); switchToNextState(DOWN); } break; case DWR_EVENT: setInActiveTimer(); try { context.sendDwaMessage(message(event), ResultCode.SUCCESS, null); } catch (Throwable e) { logger.debug("Can not send DWA, reconnecting", e); doDisconnect(); doEndConnection(); } break; case DWA_EVENT: setInActiveTimer(); watchdogSent = false; break; case SEND_MSG_EVENT: try { context.sendMessage(message(event)); } catch (Throwable e) { logger.debug("Can not send message", e); doDisconnect(); doEndConnection(); } break; default: logger.debug("Unknown event type {} in state {}", type(event), state); return false; } return true; } }, new MyState() { // SUSPECT @Override public boolean processEvent(StateEvent event) { switch (type(event)) { case DISCONNECT_EVENT: doEndConnection(); break; case TIMEOUT_EVENT: doDisconnect(); doEndConnection(); break; case STOP_EVENT: try { if (event.getData() == null) { context.sendDprMessage(DisconnectCause.REBOOTING); } else { Integer disconnectCause = (Integer) event.getData(); context.sendDprMessage(disconnectCause); } setInActiveTimer(); switchToNextState(STOPPING); } catch (Throwable e) { logger.debug("Can not send DPR", e); doDisconnect(); switchToNextState(DOWN); } break; case CER_EVENT: case CEA_EVENT: case DWA_EVENT: clearTimer(); switchToNextState(OKAY); break; case DPR_EVENT: try { int code = context.processDprMessage((IMessage) event.getData()); context.sendDpaMessage(message(event), code, null); } catch (Throwable e) { logger.debug("Can not send DPA", e); } IMessage message = (IMessage) event.getData(); try { if (message.getAvps().getAvp(Avp.DISCONNECT_CAUSE) != null && message.getAvps().getAvp(Avp.DISCONNECT_CAUSE) .getInteger32() == DisconnectCause.REBOOTING) { doDisconnect(); doEndConnection(); } else { doDisconnect(); switchToNextState(DOWN); } } catch (AvpDataException e1) { logger.warn("Disconnect cause is bad.", e1); doDisconnect(); switchToNextState(DOWN); } break; case DWR_EVENT: try { int code = context.processDwrMessage((IMessage) event.getData()); context.sendDwaMessage(message(event), code, null); switchToNextState(OKAY); } catch (Throwable e) { logger.debug("Can not send DWA", e); doDisconnect(); switchToNextState(DOWN); } break; case RECEIVE_MSG_EVENT: clearTimer(); context.receiveMessage(message(event)); switchToNextState(OKAY); break; case SEND_MSG_EVENT: // todo buffering throw new IllegalStateException("Connection is down"); default: logger.debug("Unknown event type {} in state {}", type(event), state); return false; } return true; } }, new MyState() { // DOWN @Override public void entryAction() { setTimer(0); //FIXME: baranowb: removed this, cause this breaks peers as // it seems, if peer is not removed, it will linger // without any way to process messages // if (context.isRestoreConnection()) { //PCB added FSM multithread mustRun = false; // } context.removeStatistics(); } @Override public boolean processEvent(StateEvent event) { switch (type(event)) { case START_EVENT: try { context.createStatistics(); if (!context.isConnected()) { context.connect(); } context.sendCerMessage(); setTimer(CEA_TIMEOUT); switchToNextState(INITIAL); } catch (Throwable e) { logger.debug("Connect error", e); doEndConnection(); } break; case CER_EVENT: context.createStatistics(); int resultCode = context.processCerMessage(key(event), message(event)); if (resultCode == ResultCode.SUCCESS) { try { context.sendCeaMessage(resultCode, message(event), null); switchToNextState(OKAY); } catch (Exception e) { logger.debug("Failed to send CEA.", e); doDisconnect(); // ! doEndConnection(); } } else { try { context.sendCeaMessage(resultCode, message(event), null); } catch (Exception e) { logger.debug("Failed to send CEA.", e); } doDisconnect(); // ! doEndConnection(); } break; case SEND_MSG_EVENT: // todo buffering throw new IllegalStateException("Connection is down"); case STOP_EVENT: case TIMEOUT_EVENT: case DISCONNECT_EVENT: // those are ~legal, ie. DISCONNECT_EVENT is sent back from connection break; default: logger.debug("Unknown event type {} in state {}", type(event), state); return false; } return true; } }, new MyState() { // REOPEN @Override public boolean processEvent(StateEvent event) { switch (type(event)) { case CONNECT_EVENT: try { context.sendCerMessage(); setTimer(CEA_TIMEOUT); switchToNextState(INITIAL); } catch (Throwable e) { logger.debug("Can not send CER", e); setTimer(REC_TIMEOUT); } break; case TIMEOUT_EVENT: try { context.connect(); } catch (Exception e) { logger.debug("Can not connect to remote peer", e); setTimer(REC_TIMEOUT); } break; case STOP_EVENT: setTimer(0); doDisconnect(); switchToNextState(DOWN); break; case DISCONNECT_EVENT: break; case SEND_MSG_EVENT: // todo buffering throw new IllegalStateException("Connection is down"); default: logger.debug("Unknown event type {} in state {}", type(event), state); return false; } return true; } }, new MyState() { // INITIAL @Override public void entryAction() { setTimer(CEA_TIMEOUT); } @Override public boolean processEvent(StateEvent event) { switch (type(event)) { case DISCONNECT_EVENT: setTimer(0); doEndConnection(); break; case TIMEOUT_EVENT: doDisconnect(); doEndConnection(); break; case STOP_EVENT: setTimer(0); doDisconnect(); switchToNextState(DOWN); break; case CEA_EVENT: setTimer(0); if (context.processCeaMessage(key(event), message(event))) { switchToNextState(OKAY); } else { doDisconnect(); // ! doEndConnection(); } break; case CER_EVENT: int resultCode = context.processCerMessage(key(event), message(event)); if (resultCode == ResultCode.SUCCESS) { try { context.sendCeaMessage(resultCode, message(event), null); switchToNextState(OKAY); // if other connection is win } catch (Exception e) { logger.debug("Can not send CEA", e); doDisconnect(); doEndConnection(); } } else if (resultCode == -1 || resultCode == ResultCode.NO_COMMON_APPLICATION) { doDisconnect(); doEndConnection(); } break; case SEND_MSG_EVENT: // todo buffering throw new IllegalStateException("Connection is down"); default: logger.debug("Unknown event type {} in state {}", type(event), state); return false; } return true; } }, new MyState() { // STOPPING @Override public boolean processEvent(StateEvent event) { switch (type(event)) { case TIMEOUT_EVENT: case DPA_EVENT: switchToNextState(DOWN); break; case RECEIVE_MSG_EVENT: context.receiveMessage(message(event)); break; case SEND_MSG_EVENT: throw new IllegalStateException("Stack now is stopping"); case STOP_EVENT: case DISCONNECT_EVENT: break; default: logger.debug("Unknown event type {} in state {}", type(event), state); return false; } return true; } } }; } return states; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/ApplicationIdSelector.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.helpers; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Message; import org.jdiameter.api.Selector; import org.jdiameter.client.api.IMessage; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ApplicationIdSelector implements Selector { private ApplicationId applicationId; public ApplicationIdSelector(ApplicationId applicationId) { if (applicationId == null) { throw new IllegalArgumentException("Please set application id"); } this.applicationId = applicationId; } @Override public boolean checkRule(Message message) { return message != null && ((IMessage) message).getSingleApplicationId().equals(applicationId); } @Override public ApplicationId getMetaData() { return applicationId; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/EmptyConfiguration.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.helpers; import static org.jdiameter.client.impl.helpers.ExtensionPoint.*; import static org.jdiameter.client.impl.helpers.Parameters.ExtensionName; import static org.jdiameter.client.impl.helpers.Parameters.Extensions; import static org.jdiameter.server.impl.helpers.ExtensionPoint.*; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import org.jdiameter.api.ConfigurationListener; import org.jdiameter.api.MutableConfiguration; import org.jdiameter.client.impl.helpers.ExtensionPoint; /** * This class allow create configuration class for stack * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class EmptyConfiguration extends org.jdiameter.client.impl.helpers.EmptyConfiguration implements MutableConfiguration { private final ConcurrentHashMap> listeners = new ConcurrentHashMap>(); protected EmptyConfiguration() { this(true); } /** * Create instance of class * * @param callInit true if need append default parameters */ public EmptyConfiguration(boolean callInit) { if (callInit) { add(Extensions, getInstance(). // Internal extension point add(ExtensionName, ExtensionPoint.Internal.name()) .add(InternalMetaData, "org.jdiameter.server.impl.MetaDataImpl") .add(InternalMessageParser, InternalMessageParser.defValue()) .add(InternalElementParser, InternalElementParser.defValue()) .add(InternalTransportFactory, "org.jdiameter.server.impl.io.TransportLayerFactory") .add(InternalConnectionClass, InternalConnectionClass.defValue()) .add(InternalNetworkGuard, InternalNetworkGuard.defValue()) .add(InternalPeerFsmFactory, "org.jdiameter.server.impl.fsm.FsmFactoryImpl") .add(InternalSessionFactory, InternalSessionFactory.defValue()) .add(InternalRouterEngine, "org.jdiameter.server.impl.RouterImpl") .add(InternalNetWork, "org.jdiameter.server.impl.NetworkImpl") .add(InternalStatisticFactory, InternalStatisticFactory.defValue()) .add(InternalOverloadManager, "org.jdiameter.server.impl.OverloadManagerImpl") .add(InternalRealmController, InternalRealmController.defValue()) .add(InternalAgentRedirect, InternalAgentRedirect.defValue()) .add(InternalAgentConfiguration, InternalAgentConfiguration.defValue()) .add(InternalAgentProxy, InternalAgentProxy.defValue()) .add(InternalSessionDatasource, InternalSessionDatasource.defValue()) .add(InternalTimerFacility, InternalTimerFacility.defValue()) .add(InternalPeerController, "org.jdiameter.server.impl.MutablePeerTableImpl"), getInstance(). // StackLayer extension point add(ExtensionName, ExtensionPoint.StackLayer.name()), getInstance(). // ControllerLayer extension point add(ExtensionName, ExtensionPoint.ControllerLayer.name()), getInstance(). // TransportLayer extension point add(ExtensionName, ExtensionPoint.TransportLayer.name())); } } // @Override public void setByteValue(int key, byte value) { List list = listeners.get(key); if (list != null) { boolean commit = true; for (ConfigurationListener l : list) { commit &= l.elementChanged(key, value); } if (commit) { putValue(key, value); } } else { putValue(key, value); } } @Override public void setIntValue(int key, int value) { List list = listeners.get(key); if (list != null) { boolean commit = true; for (ConfigurationListener l : list) { commit &= l.elementChanged(key, value); } if (commit) { putValue(key, value); } } else { putValue(key, value); } } @Override public void setLongValue(int key, long value) { List list = listeners.get(key); if (list != null) { boolean commit = true; for (ConfigurationListener l : list) { commit &= l.elementChanged(key, value); } if (commit) { putValue(key, value); } } else { putValue(key, value); } } @Override public void setDoubleValue(int key, double value) { List list = listeners.get(key); if (list != null) { boolean commit = true; for (ConfigurationListener l : list) { commit &= l.elementChanged(key, value); } if (commit) { putValue(key, value); } } else { putValue(key, value); } } @Override public void setByteArrayValue(int key, byte[] value) { List list = listeners.get(key); if (list != null) { boolean commit = true; for (ConfigurationListener l : list) { commit &= l.elementChanged(key, value); } if (commit) { putValue(key, value); } } else { putValue(key, value); } } @Override public void setBooleanValue(int key, boolean value) { List list = listeners.get(key); if (list != null) { boolean commit = true; for (ConfigurationListener l : list) { commit &= l.elementChanged(key, value); } if (commit) { putValue(key, value); } } else { putValue(key, value); } } @Override public void setStringValue(int key, java.lang.String value) { List list = listeners.get(key); if (list != null) { boolean commit = true; for (ConfigurationListener l : list) { commit &= l.elementChanged(key, value); } if (commit) { putValue(key, value); } } else { putValue(key, value); } } @Override public void setChildren(int key, org.jdiameter.api.Configuration... values) { List list = listeners.get(key); if (list != null) { boolean commit = true; for (ConfigurationListener l : list) { commit &= l.elementChanged(key, values); } if (commit) { putValue(key, values); } // Removed due to issue #1009 (http://code.google.com/p/mobicents/issues/detail?id=1009) // putValue(key, new EmptyConfiguration(false).add(key, values)); } else { putValue(key, values); // Removed due to issue #1009 (http://code.google.com/p/mobicents/issues/detail?id=1009) // putValue(key, new EmptyConfiguration(false).add(key, values)); } } @Override public void removeValue(int... keys) { for (int i : keys) { List list = listeners.get(i); if (list != null) { boolean rem = true; for (ConfigurationListener l : list) { rem &= l.elementChanged(i, null); } if (rem) { removeValue(i); } } } } /** * @see org.jdiameter.api.MutableConfiguration class */ @Override public void addChangeListener(ConfigurationListener listener, int... ints) { for (int i : ints) { List list = listeners.get(i); if (list == null) { list = new CopyOnWriteArrayList(); list.add(listener); } listeners.put(i, list); } } /** * @see org.jdiameter.api.MutableConfiguration class */ @Override public void removeChangeListener(ConfigurationListener listener, int... ints) { for (int i : ints) { List list = listeners.get(i); if (list != null) { list.remove(listener); if (list.size() == 0) { listeners.remove(i); } } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/ExtensionPoint.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.helpers; /** * This class provide pluggable features * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class ExtensionPoint extends org.jdiameter.client.impl.helpers.ExtensionPoint { private static final long serialVersionUID = -8220684081025349561L; /** * Network implementation class name */ public static final ExtensionPoint InternalNetWork = new ExtensionPoint("InternalNetWork", "org.jdiameter.server.impl.NetworkImpl", true); //false - so its not added to extension point so Assembler does not try to create instance! /** * Class name of network guard */ public static final ExtensionPoint InternalNetworkGuard = new ExtensionPoint("InternalNetworkGuard", "org.jdiameter.server.impl.io.tcp.NetworkGuard", false); /** * Overload manager implementation class name */ public static final ExtensionPoint InternalOverloadManager = new ExtensionPoint("InternalOverloadManager", "org.jdiameter.server.impl.OverloadManagerImpl", true); protected ExtensionPoint(String name, String defaultValue, boolean appendToInternal) { super(name, defaultValue); if (appendToInternal) { Internal.appendElements(this); } } protected ExtensionPoint(String name, org.jdiameter.client.impl.helpers.ExtensionPoint... parameters) { super(name, parameters); } protected ExtensionPoint(String name, int id, org.jdiameter.client.impl.helpers.ExtensionPoint... parameters) { super(name, id, parameters); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/Loggers.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.helpers; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Loggers extends org.jdiameter.client.impl.helpers.Loggers { private static final long serialVersionUID = 1L; /** * Logs for network operations */ public static final Loggers NetWork = new Loggers("NetWork", "netWork", "Logs the NetWork watcher"); public Loggers(String name, String fullName, String desc) { super(name, fullName, desc); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/Parameters.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.helpers; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class Parameters extends org.jdiameter.client.impl.helpers.Parameters { private static final long serialVersionUID = 1L; /** * Array of local host ip addresses property */ public static final Parameters OwnIPAddresses = new Parameters("OwnIPAddresses", Object.class); /** * On/Off duplication protection property */ public static final Parameters DuplicateProtection = new Parameters("DuplicateProtection", Boolean.class, false); /** * Duplication clear task time period property */ public static final Parameters DuplicateTimer = new Parameters("DuplicateTimer", Long.class, 4 * 60 * 1000L); /** * Maximum number of Answers to keep for duplicate detection */ public static final Parameters DuplicateSize = new Parameters("DuplicateSize", Integer.class, 5000); /** * On/Off */ public static final Parameters AcceptUndefinedPeer = new Parameters("PeerAcceptUndefinedPeer", Boolean.class, false); /** * Realm name property */ public static final Parameters RealmName = new Parameters("RealmName", String.class, ""); /** * Realm hosts property */ public static final Parameters RealmHosts = new Parameters("RealmHosts", String.class, "localhost"); /** * Realm action property */ public static final Parameters RealmLocalAction = new Parameters("RealmLocalAction", String.class, "LOCAL"); /** * Realm EntryIsDynamic */ public static final Parameters RealmEntryIsDynamic = new Parameters("RealmEntryIsDynamic", Boolean.class, false); /** * Realm EntryExpTime */ public static final Parameters RealmEntryExpTime = new Parameters("RealmEntryExpTime", Long.class, 0); /** * Overload monitor property */ public static final Parameters OverloadMonitor = new Parameters("OverloadMonitor", Object.class, ""); /** * Overload monitor entry property */ public static final Parameters OverloadMonitorEntry = new Parameters("OverloadMonitorEntry", Object.class, ""); /** * Overload monitor data property */ public static final Parameters OverloadMonitorData = new Parameters("OverloadMonitorData", Object.class, ""); /** * Overload entry Index property */ public static final Parameters OverloadEntryIndex = new Parameters("OverloadEntryIndex", Integer.class, ""); /** * Overload high threshold property */ public static final Parameters OverloadEntryhighThreshold = new Parameters("OverloadEntryhighThreshold", Double.class, ""); /** * Overload low threshold property */ public static final Parameters OverloadEntrylowThreshold = new Parameters("OverloadEntrylowThreshold", Double.class, ""); /** * Peer reconnection property property */ public static final Parameters PeerAttemptConnection = new Parameters("PeerAttemptConnection", Boolean.class, false); /** * Peer reconnection property property */ public static final Parameters NeedClientAuth = new Parameters("NeedClientAuth", Boolean.class); /** * Socket bind delay property */ public static final Parameters BindDelay = new Parameters("BindDelay", Long.class, 0L); /** * RequestTable - specifies parameters of request table. */ public static final Parameters RequestTable = new Parameters("RequestTable", Object.class, ""); public static final Parameters RequestTableSize = new Parameters("RequestTableSize", Integer.class, Integer.valueOf(10240)); public static final Parameters RequestTableClearSize = new Parameters("RequestTableClearSize", Integer.class, Integer.valueOf(2048)); /** * HA Caching name property */ public static final Parameters CachingName = new Parameters("CachingName", String.class, "diameter"); protected Parameters(String name, Class type) { super(name, type); } protected Parameters(String name, Class type, Object defValue) { super(name, type, defValue); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/XMLConfiguration.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.helpers; import static org.jdiameter.client.impl.helpers.ExtensionPoint.*; import static org.jdiameter.client.impl.helpers.Parameters.*; import static org.jdiameter.server.impl.helpers.ExtensionPoint.InternalNetWork; import static org.jdiameter.server.impl.helpers.ExtensionPoint.InternalNetworkGuard; import static org.jdiameter.server.impl.helpers.ExtensionPoint.InternalOverloadManager; import static org.jdiameter.server.impl.helpers.Parameters.*; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.jdiameter.api.Configuration; import org.jdiameter.client.impl.helpers.AppConfiguration; import org.jdiameter.client.impl.helpers.Ordinal; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * This class provide loading and verification configuration for server from XML file * * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class XMLConfiguration extends EmptyConfiguration { /** * Create instance of class and load file from defined input stream * * @param in input stream * * @throws Exception */ public XMLConfiguration(InputStream in) throws Exception { this(in, null, null, false); } /** * Create instance of class and load file from defined input stream * * @param in input stream * @param attributes attributes for DocumentBuilderFactory * @param features features for DocumentBuilderFactory * * @throws Exception */ public XMLConfiguration(InputStream in, Hashtable attributes, Hashtable features) throws Exception { this(in, attributes, features, false); } /** * Create instance of class and load file from defined file name * * @param filename configuration file name * * @throws Exception */ public XMLConfiguration(String filename) throws Exception { this(filename, null, null, false); } /** * Create instance of class and load file from defined input stream * * @param filename configuration file name * @param attributes attributes for DocumentBuilderFactory * @param features features for DocumentBuilderFactory * * @throws Exception */ public XMLConfiguration(String filename, Hashtable attributes, Hashtable features) throws Exception { this(filename, attributes, features, false); } protected XMLConfiguration(Object in, Hashtable attributes, Hashtable features, boolean nop) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); if (attributes != null) { for (String key : attributes.keySet()) { factory.setAttribute(key, attributes.get(key)); } } if (features != null) { for (String key : features.keySet()) { factory.setFeature(key, features.get(key)); } } DocumentBuilder builder = factory.newDocumentBuilder(); Document document; if (in instanceof InputStream) { document = builder.parse((InputStream) in); } else if (in instanceof String) { document = builder.parse(new File((String) in)); } else { throw new Exception("Unknown type of input data"); } validate(document); processing(document); } protected void validate(Document document) throws Exception { SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Source schemaFile = new StreamSource(getClass().getResourceAsStream("/META-INF/jdiameter-server.xsd")); Schema schema = factory.newSchema(schemaFile); Validator validator = schema.newValidator(); validator.validate(new DOMSource(document)); } protected void processing(Document document) { Element element = document.getDocumentElement(); NodeList c = element.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("LocalPeer")) { addLocalPeer(c.item(i)); } else if (nodeName.equals("Parameters")) { addParameters(c.item(i)); } else if (nodeName.equals("Security")) { addSecurity(c.item(i)); } else if (nodeName.equals("Network")) { addNetwork(c.item(i)); } else if (nodeName.equals("Extensions")) { addExtensions(c.item(i)); } } } protected void addApplications(Node node) { NodeList c = node.getChildNodes(); ArrayList items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("ApplicationID")) { Configuration m = addApplicationID(c.item(i)); if (m != null) { items.add(m); } } } add(ApplicationId, items.toArray(EMPTY_ARRAY)); } protected Configuration addApplicationID(NodeList node) { for (int i = 0; i < node.getLength(); i++) { String nodeName = node.item(i).getNodeName(); if (nodeName.equals("ApplicationID")) { return addApplicationID(node.item(i)); } } return null; } protected Configuration addApplicationID(Node node) { NodeList c = node.getChildNodes(); AppConfiguration e = getInstance(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("VendorId")) { e.add(VendorId, getLongValue(c.item(i))); } else if (nodeName.equals("AuthApplId")) { e.add(AuthApplId, getLongValue(c.item(i))); } else if (nodeName.equals("AcctApplId")) { e.add(AcctApplId, getLongValue(c.item(i))); } } return e; } protected void addParameters(Node node) { NodeList c = node.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("UseUriAsFqdn")) { add(UseUriAsFqdn, Boolean.valueOf(getValue(c.item(i)))); } else if (nodeName.equals("QueueSize")) { add(QueueSize, getIntValue(c.item(i))); } else if (nodeName.equals("MessageTimeOut")) { add(MessageTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("StopTimeOut")) { add(StopTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("CeaTimeOut")) { add(CeaTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("IacTimeOut")) { add(IacTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("DwaTimeOut")) { add(DwaTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("DpaTimeOut")) { add(DpaTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("RecTimeOut")) { add(RecTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("SessionTimeOut")) { add(SessionTimeOut, getLongValue(c.item(i))); } else if (nodeName.equals("BindDelay")) { add(BindDelay, getLongValue(c.item(i))); } else if (nodeName.equals("ThreadPool")) { addThreadPool(c.item(i)); } else if (nodeName.equals("PeerFSMThreadCount")) { add(PeerFSMThreadCount, getIntValue(c.item(i))); } else if (nodeName.equals("Statistics")) { addStatisticLogger(Statistics, c.item(i)); } else if (nodeName.equals("Concurrent")) { addConcurrent(Concurrent, c.item(i)); } else if (nodeName.equals("Dictionary")) { addDictionary(Dictionary, c.item(i)); } else if (nodeName.equals("RequestTable")) { addRequestTable(RequestTable, c.item(i)); } else { appendOtherParameter(c.item(i)); } } } protected void addThreadPool(Node item) { AppConfiguration threadPoolConfiguration = org.jdiameter.client.impl.helpers.EmptyConfiguration.getInstance(); NamedNodeMap attributes = item.getAttributes(); for (int index = 0; index < attributes.getLength(); index++) { Node n = attributes.item(index); int v = Integer.parseInt(n.getNodeValue()); if (n.getNodeName().equals("size")) { threadPoolConfiguration.add(ThreadPoolSize, v); } else if (n.getNodeName().equals("priority")) { threadPoolConfiguration.add(ThreadPoolPriority, v); } else { //log.error("Unkonwn attribute on " + item.getNodeName() + ", attribute name: " + n.getNodeName()); } } if (!threadPoolConfiguration.isAttributeExist(ThreadPoolSize.ordinal())) { threadPoolConfiguration.add(ThreadPoolSize, ThreadPoolSize.defValue()); } if (!threadPoolConfiguration.isAttributeExist(ThreadPoolPriority.ordinal())) { threadPoolConfiguration.add(ThreadPoolPriority, ThreadPoolPriority.defValue()); } this.add(ThreadPool, threadPoolConfiguration); } protected void addConcurrent(org.jdiameter.client.impl.helpers.Parameters name, Node node) { NodeList c = node.getChildNodes(); List items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Entity")) { addConcurrentEntity(items, c.item(i)); } } add(name, items.toArray(new Configuration[items.size()])); } protected void addConcurrentEntity(List items, Node node) { AppConfiguration cfg = getInstance(); String name = node.getAttributes().getNamedItem("name").getNodeValue(); cfg.add(ConcurrentEntityName, name); if (node.getAttributes().getNamedItem("description") != null) { String descr = node.getAttributes().getNamedItem("description").getNodeValue(); cfg.add(ConcurrentEntityDescription, descr); } if (node.getAttributes().getNamedItem("size") != null) { String size = node.getAttributes().getNamedItem("size").getNodeValue(); cfg.add(ConcurrentEntityPoolSize, Integer.parseInt(size)); } items.add(cfg); } protected void addStatisticLogger(org.jdiameter.client.impl.helpers.Parameters name, Node node) { String pause = node.getAttributes().getNamedItem("pause").getNodeValue(); String delay = node.getAttributes().getNamedItem("delay").getNodeValue(); String enabled = node.getAttributes().getNamedItem("enabled").getNodeValue(); String active_records; if (node.getAttributes().getNamedItem("active_records") != null) { active_records = node.getAttributes().getNamedItem("active_records").getNodeValue(); } else { active_records = (String) StatisticsActiveList.defValue(); } add(name, getInstance().add(StatisticsLoggerPause, Long.parseLong(pause)) .add(StatisticsLoggerDelay, Long.parseLong(delay)).add(StatisticsEnabled, Boolean.parseBoolean(enabled)) .add(StatisticsActiveList, active_records)); } protected void addDictionary(org.jdiameter.client.impl.helpers.Parameters name, Node node) { AppConfiguration dicConfiguration = getInstance(); Node param = node.getAttributes().getNamedItem("class"); if (param != null) { String clazz = param.getNodeValue(); dicConfiguration.add(DictionaryClass, clazz); } param = node.getAttributes().getNamedItem("enabled"); if (param != null) { String enabled = param.getNodeValue(); dicConfiguration.add(DictionaryEnabled, Boolean.valueOf(enabled)); } param = node.getAttributes().getNamedItem("sendLevel"); if (param != null) { String sendLevel = param.getNodeValue(); dicConfiguration.add(DictionarySendLevel, sendLevel); } param = node.getAttributes().getNamedItem("receiveLevel"); if (param != null) { String receiveLevel = param.getNodeValue(); dicConfiguration.add(DictionaryReceiveLevel, receiveLevel); } add(name, dicConfiguration); } protected void addRequestTable(org.jdiameter.client.impl.helpers.Parameters name, Node node) { AppConfiguration tableConfiguration = getInstance(); Node param = node.getAttributes().getNamedItem("size"); if (param != null) { String size = param.getNodeValue(); tableConfiguration.add(Parameters.RequestTableSize, Integer.parseInt(size)); } param = node.getAttributes().getNamedItem("clear_size"); if (param != null) { String size = param.getNodeValue(); tableConfiguration.add(Parameters.RequestTableClearSize, Integer.parseInt(size)); } add(name, tableConfiguration); } protected void addSecurity(Node node) { NodeList c = node.getChildNodes(); List items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("SecurityData")) { items.add(addSecurityData(c.item(i))); } } add(Security, items.toArray(EMPTY_ARRAY)); } protected Configuration addSecurityData(Node node) { AppConfiguration sd = getInstance().add(SDName, node.getAttributes().getNamedItem("name").getNodeValue()) .add(SDProtocol, node.getAttributes().getNamedItem("protocol").getNodeValue()) .add(SDEnableSessionCreation, Boolean.valueOf(node.getAttributes().getNamedItem("enable_session_creation").getNodeValue())) .add(SDUseClientMode, Boolean.valueOf(node.getAttributes().getNamedItem("use_client_mode").getNodeValue())); NodeList c = node.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { Node cnode = c.item(i); String nodeName = cnode.getNodeName(); if (nodeName.equals("CipherSuites")) { sd.add(CipherSuites, cnode.getTextContent().trim()); } if (nodeName.equals("KeyData")) { sd.add(KeyData, getInstance().add(KDManager, cnode.getAttributes().getNamedItem("manager").getNodeValue()) .add(KDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) .add(KDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) .add(KDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); } if (nodeName.equals("TrustData")) { sd.add(TrustData, getInstance().add(TDManager, cnode.getAttributes().getNamedItem("manager").getNodeValue()) .add(TDStore, cnode.getAttributes().getNamedItem("store").getNodeValue()) .add(TDFile, cnode.getAttributes().getNamedItem("file").getNodeValue()) .add(TDPwd, cnode.getAttributes().getNamedItem("pwd").getNodeValue())); } } return sd; } protected void addNetwork(Node node) { NodeList c = node.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Peers")) { addPeers(c.item(i)); } else if (nodeName.equals("Realms")) { addRealms(c.item(i)); } } } protected void addPeers(Node node) { NodeList c = node.getChildNodes(); ArrayList items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Peer")) { items.add(addPeer(c.item(i))); } } add(PeerTable, items.toArray(EMPTY_ARRAY)); } protected void addRealms(Node node) { NodeList c = node.getChildNodes(); ArrayList items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Realm")) { items.add(addRealm(c.item(i))); } } add(RealmTable, items.toArray(EMPTY_ARRAY)); } protected Configuration addPeer(Node node) { String rating = node.getAttributes().getNamedItem("rating").getNodeValue(); String connecting = node.getAttributes().getNamedItem("attempt_connect").getNodeValue(); String name = node.getAttributes().getNamedItem("name").getNodeValue(); AppConfiguration c = getInstance(); c.add(PeerRating, Integer.parseInt(rating)); c.add(PeerAttemptConnection, Boolean.valueOf(connecting)); c.add(PeerName, name); if (node.getAttributes().getNamedItem("ip") != null) { c.add(PeerIp, node.getAttributes().getNamedItem("ip").getNodeValue()); } if (node.getAttributes().getNamedItem("portRange") != null) { c.add(PeerLocalPortRange, node.getAttributes().getNamedItem("portRange").getNodeValue()); } if (node.getAttributes().getNamedItem("security_ref") != null) { c.add(SecurityRef, node.getAttributes().getNamedItem("security_ref").getNodeValue()); } return c; } protected void addLocalPeer(Node node) { NodeList c = node.getChildNodes(); if (node.getAttributes().getNamedItem("security_ref") != null) { add(SecurityRef, node.getAttributes().getNamedItem("security_ref").getNodeValue()); } for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("URI")) { add(OwnDiameterURI, getValue(c.item(i))); } addIPAddress(c.item(i)); if (nodeName.equals("Realm")) { add(OwnRealm, getValue(c.item(i))); } if (nodeName.equals("VendorID")) { add(OwnVendorID, getLongValue(c.item(i))); } if (nodeName.equals("ProductName")) { add(OwnProductName, getValue(c.item(i))); } if (nodeName.equals("FirmwareRevision")) { add(OwnFirmwareRevision, getLongValue(c.item(i))); } if (nodeName.equals("Applications")) { addApplications(c.item(i)); } if (nodeName.equals("OverloadMonitor")) { addOverloadMonitor(c.item(i)); } } } private void addOverloadMonitor(Node node) { NodeList c = node.getChildNodes(); ArrayList items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("Entry")) { items.add(addOverloadMonitorItem(c.item(i))); } } add(OverloadMonitor, items.toArray(EMPTY_ARRAY)); } private Configuration addOverloadMonitorItem(Node node) { return getInstance().add(OverloadEntryIndex, Integer.valueOf(getAttrValue(node, "index"))) .add(OverloadEntrylowThreshold, Double.valueOf(getAttrValue(node, "lowThreshold"))) .add(OverloadEntryhighThreshold, Double.valueOf(getAttrValue(node, "highThreshold"))) .add(ApplicationId, addApplicationID(node.getChildNodes())); } protected void addIPAddress(Node node) { String nodeName = node.getNodeName(); if (nodeName.equals("IPAddresses")) { addIPAddresses(node); } } private void addIPAddresses(Node node) { NodeList c = node.getChildNodes(); ArrayList items = new ArrayList(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("IPAddress")) { items.add(addIPAddressItem(c.item(i))); } } add(OwnIPAddresses, items.toArray(EMPTY_ARRAY)); } protected Configuration addIPAddressItem(Node node) { return getInstance().add(OwnIPAddress, getValue(node)); } protected Configuration addRealm(Node node) { AppConfiguration realmEntry = getInstance(); realmEntry.add(ApplicationId, new Configuration[] { addApplicationID(node.getChildNodes()) }) .add(RealmName, getAttrValue(node, "name")).add(RealmHosts, getAttrValue(node, "peers")) .add(RealmLocalAction, getAttrValue(node, "local_action")) .add(RealmEntryIsDynamic, Boolean.valueOf(getAttrValue(node, "dynamic"))) .add(RealmEntryExpTime, Long.valueOf(getAttrValue(node, "exp_time"))); NodeList childNodes = node.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { String nodeName = childNodes.item(i).getNodeName(); if (nodeName.equals("Agent")) { realmEntry.add(Agent, addAgent(childNodes.item(i))); } } return getInstance().add(RealmEntry, realmEntry); } protected Configuration addAgent(Node node) { AppConfiguration agentConf = getInstance(); NodeList agentChildren = node.getChildNodes(); for (int index = 0; index < agentChildren.getLength(); index++) { Node n = agentChildren.item(index); if (n.getNodeName().equals("Properties")) { agentConf.add(Properties, getProperties(n).toArray(EMPTY_ARRAY)); } } return agentConf; } protected List getProperties(Node node) { List props = new ArrayList(); NodeList propertiesChildren = node.getChildNodes(); for (int index = 0; index < propertiesChildren.getLength(); index++) { Node n = propertiesChildren.item(index); if (n.getNodeName().equals("Property")) { AppConfiguration property = getInstance(); property.add(PropertyName, n.getAttributes().getNamedItem(PropertyName.name()).getNodeValue()); property.add(PropertyValue, n.getAttributes().getNamedItem(PropertyValue.name()).getNodeValue()); props.add(property); } } return props; } protected void appendOtherParameter(Node node) { String nodeName = node.getNodeName(); if (nodeName.equals("DuplicateProtection")) { add(DuplicateProtection, Boolean.valueOf(getValue(node))); } if (nodeName.equals("DuplicateTimer")) { add(DuplicateTimer, getLongValue(node)); } if (nodeName.equals("DuplicateSize")) { add(DuplicateSize, getIntValue(node)); } if (nodeName.equals("AcceptUndefinedPeer")) { add(AcceptUndefinedPeer, Boolean.valueOf(getValue(node))); } } protected void addExtensions(Node node) { NodeList c = node.getChildNodes(); for (int i = 0; i < c.getLength(); i++) { String nodeName = c.item(i).getNodeName(); if (nodeName.equals("MetaData")) { addInternalExtension(InternalMetaData, getValue(c.item(i))); } else if (nodeName.equals("MessageParser")) { addInternalExtension(InternalMessageParser, getValue(c.item(i))); } else if (nodeName.equals("ElementParser")) { addInternalExtension(InternalElementParser, getValue(c.item(i))); } else if (nodeName.equals("RouterEngine")) { addInternalExtension(InternalRouterEngine, getValue(c.item(i))); } else if (nodeName.equals("PeerController")) { addInternalExtension(InternalPeerController, getValue(c.item(i))); } else if (nodeName.equals("RealmController")) { addInternalExtension(InternalRealmController, getValue(c.item(i))); } else if (nodeName.equals("SessionFactory")) { addInternalExtension(InternalSessionFactory, getValue(c.item(i))); } else if (nodeName.equals("TransportFactory")) { addInternalExtension(InternalTransportFactory, getValue(c.item(i))); } else if (nodeName.equals("Connection")) { addInternalExtension(InternalConnectionClass, getValue(c.item(i))); } else if (nodeName.equals("NetworkGuard")) { addInternalExtension(InternalNetworkGuard, getValue(c.item(i))); } else if (nodeName.equals("PeerFsmFactory")) { addInternalExtension(InternalPeerFsmFactory, getValue(c.item(i))); } else if (nodeName.equals("StatisticFactory")) { addInternalExtension(InternalStatisticFactory, getValue(c.item(i))); } else if (nodeName.equals("ConcurrentFactory")) { addInternalExtension(InternalConcurrentFactory, getValue(c.item(i))); } else if (nodeName.equals("ConcurrentEntityFactory")) { addInternalExtension(InternalConcurrentEntityFactory, getValue(c.item(i))); } else if (nodeName.equals("StatisticProcessor")) { addInternalExtension(InternalStatisticProcessor, getValue(c.item(i))); } else if (nodeName.equals("NetWork")) { addInternalExtension(InternalNetWork, getValue(c.item(i))); } else if (nodeName.equals("SessionDatasource")) { addInternalExtension(InternalSessionDatasource, getValue(c.item(i))); } else if (nodeName.equals("TimerFacility")) { addInternalExtension(InternalTimerFacility, getValue(c.item(i))); } else if (nodeName.equals("AgentRedirect")) { addInternalExtension(InternalAgentRedirect, getValue(c.item(i))); } else if (nodeName.equals("AgentConfiguration")) { add(org.jdiameter.client.impl.helpers.ExtensionPoint.InternalAgentConfiguration, getValue(c.item(i))); } else if (nodeName.equals("AgentProxy")) { addInternalExtension(InternalAgentProxy, getValue(c.item(i))); } else if (nodeName.equals("OverloadManager")) { addInternalExtension(InternalOverloadManager, getValue(c.item(i))); } else { appendOtherExtension(c.item(i)); } } } protected void addInternalExtension(Ordinal ep, String value) { Configuration[] extensionConfs = this.getChildren(org.jdiameter.client.impl.helpers.Parameters.Extensions.ordinal()); AppConfiguration internalExtensions = (AppConfiguration) extensionConfs[org.jdiameter.client.impl.helpers.ExtensionPoint.Internal .id()]; internalExtensions.add(ep, value); } private void appendOtherExtension(Node item) { // Nothing to do here, so far } protected Long getLongValue(Node node) { return Long.valueOf(getValue(node)); } protected Integer getIntValue(Node node) { return Integer.valueOf(getValue(node)); } protected String getValue(Node node) { return node.getAttributes().getNamedItem("value").getNodeValue(); } protected String getAttrValue(Node node, String name) { return node.getAttributes().getNamedItem(name).getNodeValue(); } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/io/TransportLayerFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.io; import static java.lang.Class.forName; import java.lang.reflect.Constructor; import java.net.InetAddress; import org.jdiameter.api.Configuration; import org.jdiameter.client.api.io.TransportError; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.helpers.AppConfiguration; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.server.api.IMetaData; import org.jdiameter.server.api.io.INetworkConnectionListener; import org.jdiameter.server.api.io.INetworkGuard; import org.jdiameter.server.api.io.ITransportLayerFactory; import org.jdiameter.server.impl.helpers.ExtensionPoint; /** * @author erick.svenson@yahoo.com * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class TransportLayerFactory extends org.jdiameter.client.impl.transport.TransportLayerFactory implements ITransportLayerFactory { private final IConcurrentFactory concurrentFactory; private final IMetaData metaData; private Class networkGuardClass; private Constructor networkGuardConstructor; public TransportLayerFactory(Configuration conf, IConcurrentFactory concurrentFactory, IMessageParser parser, IMetaData metaData) throws TransportException { super(conf, parser); this.concurrentFactory = concurrentFactory; this.metaData = metaData; String networkGuardClassName = null; Configuration[] children = config.getChildren(org.jdiameter.client.impl.helpers.Parameters.Extensions.ordinal()); // extract network guard class name. AppConfiguration internalExtensions = (AppConfiguration) children[org.jdiameter.client.impl.helpers.ExtensionPoint.Internal .id()]; networkGuardClassName = internalExtensions.getStringValue(ExtensionPoint.InternalNetworkGuard.ordinal(), ExtensionPoint.InternalNetworkGuard.defValue()); try { // TODO: this should be enough to check if class has interface!? this.networkGuardClass = (Class) forName(networkGuardClassName); if (!INetworkGuard.class.isAssignableFrom(this.networkGuardClass)) { throw new TransportException( "Specified class does not inherit INetworkGuard interface " + this.networkGuardClass, TransportError.Internal); } } catch (Exception e) { throw new TransportException("Cannot prepare specified guard class " + this.networkGuardClass, TransportError.Internal, e); } try { // TODO: this is bad practice, IConnection is interface and this code enforces constructor type to be present! networkGuardConstructor = this.networkGuardClass.getConstructor(InetAddress[].class, Integer.TYPE, IConcurrentFactory.class, IMessageParser.class, IMetaData.class); } catch (Exception e) { throw new TransportException("Cannot find required constructor", TransportError.Internal, e); } } @Override public INetworkGuard createNetworkGuard(InetAddress inetAddress, int port) throws TransportException { try { return networkGuardConstructor.newInstance(inetAddress, port, this.concurrentFactory, this.parser, this.metaData); } catch (Exception e) { throw new TransportException(TransportError.NetWorkError, e); } } @Override public INetworkGuard createNetworkGuard(InetAddress inetAddress, final int port, final INetworkConnectionListener listener) throws TransportException { INetworkGuard guard; try { guard = networkGuardConstructor.newInstance(inetAddress, port, this.concurrentFactory, this.parser, this.metaData); } catch (Exception e) { throw new TransportException(TransportError.NetWorkError, e); } guard.addListener(listener); return guard; } @Override public INetworkGuard createNetworkGuard(InetAddress[] inetAddress, int port) throws TransportException { try { return networkGuardConstructor.newInstance(inetAddress, port, this.concurrentFactory, this.parser, this.metaData); } catch (Exception e) { throw new TransportException(TransportError.NetWorkError, e); } } @Override public INetworkGuard createNetworkGuard(InetAddress[] inetAddress, int port, INetworkConnectionListener listener) throws TransportException { INetworkGuard guard; try { guard = networkGuardConstructor.newInstance(inetAddress, port, this.concurrentFactory, this.parser, this.metaData); } catch (Exception e) { throw new TransportException(TransportError.NetWorkError, e); } guard.addListener(listener); return guard; } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/io/tcp/NetworkGuard.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2014, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.io.tcp; import static org.jdiameter.server.impl.helpers.Parameters.BindDelay; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.transport.tcp.TCPClientConnection; import org.jdiameter.common.api.concurrent.DummyConcurrentFactory; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.server.api.IMetaData; import org.jdiameter.server.api.io.INetworkConnectionListener; import org.jdiameter.server.api.io.INetworkGuard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * TCP implementation of {@link org.jdiameter.server.api.io.INetworkGuard}. * * @author Alexandre Mendonca * @author Bartosz Baranowski */ @SuppressWarnings("all") //3rd party lib public class NetworkGuard implements INetworkGuard { private static final Logger logger = LoggerFactory.getLogger(NetworkGuard.class); protected IMessageParser parser; protected IConcurrentFactory concurrentFactory; protected int port; protected long bindDelay; protected CopyOnWriteArrayList listeners = new CopyOnWriteArrayList(); protected boolean isWork = false; // protected Selector selector; // protected ServerSocket serverSocket; //private Thread thread; private List tasks = new ArrayList(); @Deprecated public NetworkGuard(InetAddress inetAddress, int port, IMessageParser parser) throws Exception { this(inetAddress, port, null, parser, null); } public NetworkGuard(InetAddress inetAddress, int port, IConcurrentFactory concurrentFactory, IMessageParser parser, IMetaData data) throws Exception { this(new InetAddress[] { inetAddress }, port, concurrentFactory, parser, data); } public NetworkGuard(InetAddress[] inetAddress, int port, IConcurrentFactory concurrentFactory, IMessageParser parser, IMetaData data) throws Exception { this.port = port; this.parser = parser; this.concurrentFactory = concurrentFactory == null ? new DummyConcurrentFactory() : concurrentFactory; //this.thread = this.concurrentFactory.getThread("NetworkGuard", this); this.bindDelay = data.getConfiguration().getLongValue(BindDelay.ordinal(), (Long) BindDelay.defValue()); try { for (int addrIdx = 0; addrIdx < inetAddress.length; addrIdx++) { GuardTask guardTask = new GuardTask(new InetSocketAddress(inetAddress[addrIdx], port)); this.concurrentFactory.getThreadPool().execute(guardTask); tasks.add(guardTask); } isWork = true; } catch (Exception exc) { destroy(); throw new Exception(exc); } } @Override public void addListener(INetworkConnectionListener listener) { if (!listeners.contains(listener)) { listeners.add(listener); } } @Override public void remListener(INetworkConnectionListener listener) { listeners.remove(listener); } @Override public String toString() { return "NetworkGuard:" + (this.tasks.size() != 0 ? this.tasks : "closed"); } @Override public void destroy() { isWork = false; Iterator it = this.tasks.iterator(); while (it.hasNext()) { GuardTask gt = it.next(); it.remove(); gt.cleanTask(); } } private class GuardTask implements Runnable { private Thread thread; private Selector selector; private ServerSocket serverSocket; private final ScheduledExecutorService binder = Executors.newSingleThreadScheduledExecutor(); GuardTask(final InetSocketAddress addr) throws IOException { if (bindDelay > 0) { logger.info("Socket binding will be delayed by {}ms...", bindDelay); } Runnable task = new Runnable() { @Override public void run() { try { logger.debug("Binding {} after delaying {}ms...", addr, bindDelay); final ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); serverSocket = ssc.socket(); serverSocket.bind(addr); selector = Selector.open(); ssc.register(selector, SelectionKey.OP_ACCEPT, addr); logger.info("Open server socket {} ", serverSocket); } catch (IOException e) { throw new RuntimeException(e); } } }; binder.schedule(task, bindDelay, TimeUnit.MILLISECONDS); } public void start() { this.thread.start(); } @Override public void run() { try { while (isWork) { if (selector == null) { logger.trace("Selector is still null, stack is waiting for binding..."); Thread.sleep(250); continue; } // without timeout when we kill socket, this causes errors, bug in VM ? int num = selector.select(100); if (num == 0) { continue; } Set keys = selector.selectedKeys(); try { for (SelectionKey key : keys) { if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { try { Socket s = serverSocket.accept(); logger.info("Open incomming connection {}", s); TCPClientConnection client = new TCPClientConnection(null, concurrentFactory, s, parser, null); // PCB added logging logger.debug("Finished initialising TCPClientConnection for {}", s); for (INetworkConnectionListener listener : listeners) { listener.newNetworkConnection(client); } } catch (Exception e) { logger.warn("Can not create incoming connection", e); } } } } catch (Exception e) { logger.debug("Failed to accept connection,", e); } finally { keys.clear(); } } } catch (Exception exc) { logger.warn("Server socket stopped", exc); } } public void cleanTask() { try { if (thread != null) { thread.join(2000); if (thread.isAlive()) { // FIXME: remove ASAP thread.interrupt(); } thread = null; } } catch (InterruptedException e) { logger.debug("Can not stop thread", e); } if (selector != null) { try { selector.close(); } catch (Exception e) { // ignore } selector = null; } if (serverSocket != null) { try { serverSocket.close(); } catch (Exception e) { // ignore } serverSocket = null; } } @Override public String toString() { return "GuardTask [serverSocket=" + serverSocket + "]"; } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/io/tcp/netty/NetworkGuard.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.server.impl.io.tcp.netty; import static org.jdiameter.server.impl.helpers.Parameters.BindDelay; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.transport.tcp.netty.TCPClientConnection; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.server.api.IMetaData; import org.jdiameter.server.api.io.INetworkConnectionListener; import org.jdiameter.server.api.io.INetworkGuard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; /** * TCP implementation of {@link org.jdiameter.server.api.io.INetworkGuard}. * * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class NetworkGuard implements INetworkGuard { private static final Logger logger = LoggerFactory.getLogger(NetworkGuard.class); protected CopyOnWriteArrayList listeners = new CopyOnWriteArrayList(); protected IMessageParser parser; protected int port; protected InetAddress[] localAddresses; protected long bindDelay; protected final EventLoopGroup bossGroup = new NioEventLoopGroup(); protected final EventLoopGroup workerGroup = new NioEventLoopGroup(); protected List channels = new CopyOnWriteArrayList(); protected final ScheduledExecutorService binderExecutor = Executors.newSingleThreadScheduledExecutor(); Runnable binderTask = new Runnable() { public void run() { bindAll(); } }; private void bindAll() { for (int i = 0; i < localAddresses.length; i++) { bind(new InetSocketAddress(localAddresses[i], port)); } } private void bind(InetSocketAddress localAddress) { logger.debug("Binding to socket [{}]", localAddress); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ClientHandler()); } }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true); try { channels.add(bootstrap.bind(localAddress).sync().channel()); logger.debug("Bound to socket [{}]", localAddress); } catch (InterruptedException e) { logger.error("Failed to bind to socket " + localAddress, e); } /* * bootstrap.bind(port).addListener(new ChannelFutureListener() { * * @Override public void operationComplete(ChannelFuture channelFuture) throws Exception { if * (channelFuture.isSuccess()) { * channels.add(channelFuture.channel()); } } }); */ } @SuppressWarnings("all") //3rd party lib public class ClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(final ChannelHandlerContext ctx) { logger.debug("Received connection on socket [{}] from [{}]", ctx.channel().localAddress(), ctx.channel().remoteAddress()); TCPClientConnection client = new TCPClientConnection(ctx.channel(), parser); for (INetworkConnectionListener listener : listeners) { listener.newNetworkConnection(client); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.error(cause.getMessage(), cause); } } @Deprecated public NetworkGuard(InetAddress inetAddress, int port, IMessageParser parser) throws Exception { this(inetAddress, port, null, parser, null); } public NetworkGuard(InetAddress inetAddress, int port, IConcurrentFactory concurrentFactory, IMessageParser parser, IMetaData data) throws Exception { this(new InetAddress[] { inetAddress }, port, concurrentFactory, parser, data); } public NetworkGuard(InetAddress[] inetAddress, int port, IConcurrentFactory concurrentFactory, IMessageParser parser, IMetaData data) throws Exception { this.parser = parser; this.localAddresses = inetAddress; this.port = port; this.bindDelay = data.getConfiguration().getLongValue(BindDelay.ordinal(), (Long) BindDelay.defValue()); this.binderExecutor.schedule(binderTask, bindDelay, TimeUnit.MILLISECONDS); } public void addListener(INetworkConnectionListener listener) { if (!listeners.contains(listener)) { listeners.add(listener); } } public void remListener(INetworkConnectionListener listener) { listeners.remove(listener); } @Override public String toString() { return "NetworkGuard:" + (this.localAddresses.length != 0 ? this.localAddresses : "closed"); } public void destroy() { logger.debug("Destroying network guard"); closeChannels(); closeWorkerGroup(); closeBossGroup(); binderExecutor.shutdown(); } private void closeWorkerGroup() { try { workerGroup.shutdownGracefully().sync(); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } private void closeBossGroup() { try { bossGroup.shutdownGracefully().sync(); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } private void closeChannels() { for (Channel channel : channels) { try { logger.debug("Closing channel on socket [{}]", channel.localAddress()); channel.close().sync(); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/io/tls/NetworkGuard.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.server.impl.io.tls; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.CopyOnWriteArrayList; import org.jdiameter.api.Configuration; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.transport.tls.TLSClientConnection; import org.jdiameter.client.impl.transport.tls.TLSUtils; import org.jdiameter.common.api.concurrent.DummyConcurrentFactory; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.server.api.IMetaData; import org.jdiameter.server.api.io.INetworkConnectionListener; import org.jdiameter.server.api.io.INetworkGuard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * TLS implementation of {@link org.jdiameter.server.api.io.INetworkGuard}. * * @author Bartosz Baranowski * @author Alexandre Mendonca */ @SuppressWarnings("all") //3rd party lib public class NetworkGuard implements INetworkGuard, Runnable { private static final Logger logger = LoggerFactory.getLogger(NetworkGuard.class); private IMessageParser parser; private IConcurrentFactory concurrentFactory; private int port; private CopyOnWriteArrayList listeners = new CopyOnWriteArrayList(); private boolean isWork = false; // private SSLServerSocket serverSocket; private ServerSocket serverSocket; private Configuration localPeerSSLConfig; private Thread thread; private String secRef; public NetworkGuard(InetAddress inetAddress, int port, IConcurrentFactory concurrentFactory, IMessageParser parser, IMetaData data) throws Exception { this.port = port; this.parser = parser; this.concurrentFactory = concurrentFactory == null ? new DummyConcurrentFactory() : concurrentFactory; // this.thread = this.concurrentFactory.getThread("NetworkGuard", this); // extract sec_ref from local peer; Configuration conf = data.getConfiguration(); if (!conf.isAttributeExist(org.jdiameter.client.impl.helpers.Parameters.SecurityRef.ordinal())) { throw new IllegalArgumentException("No security_ref attribute present in local peer!"); } String secRef = conf.getStringValue(org.jdiameter.client.impl.helpers.Parameters.SecurityRef.ordinal(), ""); // now need to get proper security data. this.localPeerSSLConfig = TLSUtils.getSSLConfiguration(conf, secRef); if (this.localPeerSSLConfig == null) { throw new IllegalArgumentException("No Security for security_reference '" + secRef + "'"); } // SSLContext sslContext = TLSUtils.getSecureContext(localPeerSSLConfig); try { // SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory(); // this.serverSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(); this.serverSocket = new ServerSocket(); this.serverSocket.bind(new InetSocketAddress(inetAddress, port)); this.isWork = true; logger.info("Open server socket {} ", serverSocket); this.concurrentFactory.getThreadPool().execute(this); } catch (Exception exc) { destroy(); throw new Exception(exc); } } @Override public void run() { try { while (this.isWork) { // without timeout when we kill socket, this causes errors, bug in VM ? try { Socket clientConnection = serverSocket.accept(); logger.info("Open incomming SSL connection {}", clientConnection); TLSClientConnection client = new TLSClientConnection(null, this.localPeerSSLConfig, this.concurrentFactory, clientConnection, parser); this.notifyListeners(client); } catch (Exception e) { logger.debug("Failed to accept connection,", e); } } } catch (Exception exc) { logger.warn("Server socket stopped", exc); } } /* * (non-Javadoc) * * @see org.jdiameter.server.api.io.INetworkGuard#addListener(org.jdiameter.server .api.io.INetworkConnectionListener) */ @Override public void addListener(INetworkConnectionListener listener) { if (!this.listeners.contains(listener)) { this.listeners.add(listener); } } /* * (non-Javadoc) * * @see org.jdiameter.server.api.io.INetworkGuard#remListener(org.jdiameter.server .api.io.INetworkConnectionListener) */ @Override public void remListener(INetworkConnectionListener listener) { this.listeners.remove(listener); } /* * (non-Javadoc) * * @see org.jdiameter.server.api.io.INetworkGuard#destroy() */ @Override public void destroy() { try { this.isWork = false; try { if (this.thread != null) { this.thread.join(2000); if (this.thread.isAlive()) { // FIXME: remove ASAP this.thread.interrupt(); } thread = null; } } catch (InterruptedException e) { logger.debug("Can not stop thread", e); } if (this.serverSocket != null) { this.serverSocket.close(); this.serverSocket = null; } } catch (IOException e) { logger.error("", e); } } // ------------------------- private section --------------------------- private void notifyListeners(TLSClientConnection client) { for (INetworkConnectionListener listener : this.listeners) { try { listener.newNetworkConnection(client); } catch (Exception e) { logger.debug("Connection listener threw exception!", e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/io/tls/netty/NetworkGuard.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.server.impl.io.tls.netty; import static org.jdiameter.server.impl.helpers.Parameters.BindDelay; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.jdiameter.api.Configuration; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.transport.tls.TLSUtils; import org.jdiameter.client.impl.transport.tls.netty.TLSClientConnection; import org.jdiameter.common.api.concurrent.DummyConcurrentFactory; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import org.jdiameter.server.api.IMetaData; import org.jdiameter.server.api.io.INetworkConnectionListener; import org.jdiameter.server.api.io.INetworkGuard; import org.jdiameter.server.impl.helpers.Parameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; /** * @author Jehanzeb Qayyum */ @SuppressWarnings("all") //3rd party lib public class NetworkGuard implements INetworkGuard { private static final Logger logger = LoggerFactory.getLogger(NetworkGuard.class); protected CopyOnWriteArrayList listeners = new CopyOnWriteArrayList(); protected IMessageParser parser; protected int port; protected InetAddress[] localAddresses; private Configuration localPeerSSLConfig; private IConcurrentFactory concurrentFactory; protected long bindDelay; protected final EventLoopGroup bossGroup = new NioEventLoopGroup(); protected final EventLoopGroup workerGroup = new NioEventLoopGroup(); protected List channels = new CopyOnWriteArrayList(); protected final ScheduledExecutorService binderExecutor = Executors.newSingleThreadScheduledExecutor(); Runnable binderTask = new Runnable() { public void run() { bindAll(); } }; private void bindAll() { for (int i = 0; i < localAddresses.length; i++) { bind(new InetSocketAddress(localAddresses[i], port)); } } private void bind(InetSocketAddress localAddress) { logger.debug("Binding to socket [{}]", localAddress); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ClientHandler()); } }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true); try { channels.add(bootstrap.bind(localAddress).sync().channel()); logger.debug("Bound to socket [{}]", localAddress); } catch (InterruptedException e) { logger.error("Failed to bind to socket " + localAddress, e); } } @SuppressWarnings("all") //3rd party lib public class ClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(final ChannelHandlerContext ctx) throws Exception { logger.debug("Received connection on socket [{}] from [{}]", ctx.channel().localAddress(), ctx.channel().remoteAddress()); TLSClientConnection client = new TLSClientConnection(null, NetworkGuard.this.localPeerSSLConfig, NetworkGuard.this.concurrentFactory, parser, ctx.channel()); for (INetworkConnectionListener listener : listeners) { listener.newNetworkConnection(client); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.error(cause.getMessage(), cause); } } @Deprecated public NetworkGuard(InetAddress inetAddress, int port, IMessageParser parser) throws Exception { this(inetAddress, port, null, parser, null); } public NetworkGuard(InetAddress inetAddress, int port, IConcurrentFactory concurrentFactory, IMessageParser parser, IMetaData data) throws Exception { this(new InetAddress[] { inetAddress }, port, concurrentFactory, parser, data); } public NetworkGuard(InetAddress[] inetAddress, int port, IConcurrentFactory concurrentFactory, IMessageParser parser, IMetaData data) throws Exception { this.parser = parser; this.localAddresses = inetAddress; this.port = port; this.concurrentFactory = concurrentFactory == null ? new DummyConcurrentFactory() : concurrentFactory; // extract sec_ref from local peer; Configuration conf = data.getConfiguration(); if (!conf.isAttributeExist(Parameters.SecurityRef.ordinal())) { throw new IllegalArgumentException("No security_ref attribute present in local peer!"); } String secRef = conf.getStringValue(Parameters.SecurityRef.ordinal(), ""); logger.debug("secRef: {}", secRef); // now need to get proper security data. this.localPeerSSLConfig = TLSUtils.getSSLConfiguration(conf, secRef); if (this.localPeerSSLConfig == null) { throw new IllegalArgumentException("No Security for security_reference '" + secRef + "'"); } this.bindDelay = data.getConfiguration().getLongValue(BindDelay.ordinal(), (Long) BindDelay.defValue()); this.binderExecutor.schedule(binderTask, bindDelay, TimeUnit.MILLISECONDS); } public void addListener(INetworkConnectionListener listener) { if (!listeners.contains(listener)) { listeners.add(listener); } } public void remListener(INetworkConnectionListener listener) { listeners.remove(listener); } @Override public String toString() { return "NetworkGuard:" + (this.localAddresses.length != 0 ? this.localAddresses : "closed"); } public void destroy() { logger.debug("Destroying network guard"); closeChannels(); closeWorkerGroup(); closeBossGroup(); binderExecutor.shutdown(); } private void closeWorkerGroup() { try { workerGroup.shutdownGracefully().sync(); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } private void closeBossGroup() { try { bossGroup.shutdownGracefully().sync(); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } private void closeChannels() { for (Channel channel : channels) { try { logger.debug("Closing channel on socket [{}]", channel.localAddress()); channel.close().sync(); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } } } ================================================ FILE: core/jdiameter/impl/src/main/resources/META-INF/agpl-3.0.txt ================================================ GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . ================================================ FILE: core/jdiameter/impl/src/main/resources/META-INF/jdiameter-client.xsd ================================================ JDiameter Client configuration Local peer parameters Local peer uri. Local peer ip address. Local peer realm. Local peer vendor identificator. Product name of stack. Firmware revision of stack. Local peer default applications ApplicationID of application Vendor id. Authentication application id. Accounting application id. Stack parameters Set Origin-Host-Name Avp as Uri into CER message. Default value is false True if virtual threads should be used QueueSize of fsm event queue Message time out in milliseconds. Session idle time out in milliseconds. Default stop time out in milliseconds. CEA command time out in milliseconds. Value of inactive time in milliseconds. DWA command time out in milliseconds. DPA command time out in milliseconds. Peer reconnect pause in milliseconds. Peer FSM Thread Count. Statistics configuration Dictionary and Validator configuration Router Request Table cache configuration Sets java class name of connection used for transport, by default its set to 'org.jdiameter.client.impl.transport.tcp.TCPClientConnection' Parameters of concurrent part of stack Concurrent entity Network descriptions Network peers Peer description. Realms description Realm description Security descriptions SSL description Cipher suites separated by ',' Key description Trust description Extension parameters ================================================ FILE: core/jdiameter/impl/src/main/resources/META-INF/jdiameter-server.xsd ================================================ JDiameter Client configuration Local peer parameters Local peer uri. Local peer realm. Local peer vendor identificator. Product name of stack. Firmware revision of stack. Local peer ip addresses Local peer overload monitor table Local peer default applications ApplicationID of application Vendor id. Authentication application id. Accounting application id. Stack parameters True if local peer must accept undefined peers True if virtual threads should be used True if duplication protection is ON Live time of duplication entry Number of duplicate answers to store Set Origin-Host-Name Avp as Uri into CER message. Default value is false QueueSize of fsm event queue Message time out in milliseconds. Session idle time out in milliseconds. Default stop time out in milliseconds. CEA command time out in milliseconds. Value of inactive time in milliseconds. DWA command time out in milliseconds. DPA command time out in milliseconds. Peer reconnect pause in milliseconds. Server Socket bind delay in milliseconds. Peer FSM Thread Count. Statistics configuration Dictionary and Validator configuration Router Request Table cache configuration Sets java class name of connection used for transport, by default its set to 'org.jdiameter.client.impl.transport.tcp.TCPClientConnection' Parameters of concurrent part of stack Concurrent entity Network descriptions Network peers Peer description. Realms description Realm description Security descriptions SSL description Cipher suites separated by ',' Key description Trust description Extension parameters ================================================ FILE: core/jdiameter/impl/src/main/resources/META-INF/version.properties ================================================ version=${project.version} vendor=${vendor} ================================================ FILE: core/jdiameter/impl/src/main/resources/dictionary.xml ================================================ /> ================================================ FILE: core/jdiameter/impl/src/test/java/org/jdiameter/client/impl/router/TestRouter.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, Telestax Inc and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.client.impl.router; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.IOException; import java.net.InetAddress; import java.net.URISyntaxException; import java.net.UnknownServiceException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import org.jdiameter.api.*; import org.jdiameter.api.app.StateChangeListener; import org.jdiameter.client.api.IAnswer; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.IRequest; import org.jdiameter.client.api.controller.IPeer; import org.jdiameter.client.api.controller.IRealmTable; import org.jdiameter.client.api.fsm.EventTypes; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.impl.helpers.XMLConfiguration; import org.jdiameter.common.api.statistic.IStatistic; import org.jdiameter.common.api.statistic.IStatisticManager; import org.jdiameter.common.api.statistic.IStatisticRecord; import org.jdiameter.common.impl.controller.AbstractPeer; import org.jdiameter.common.impl.statistic.StatisticManagerImpl; import org.jdiameter.server.api.agent.IAgentConfiguration; import org.junit.jupiter.api.Test; /** * Various testcases for Router implementations * * @author Nils Sowen */ @SuppressWarnings("all") public class TestRouter { @Test public void testWeightedRoundRobin() throws Exception { Configuration config = new XMLConfiguration("src/test/resources/jdiameter-weightedroundrobin-config.xml"); WeightedRoundRobinRouter router = new WeightedRoundRobinRouter(new RealmTableTest(), config); IStatisticManager manager = new StatisticManagerImpl(config); PeerTest p1 = new PeerTest(1, 1, true, manager); PeerTest p2 = new PeerTest(2, 1, true, manager); PeerTest p3 = new PeerTest(3, 1, true, manager); PeerTest p4 = new PeerTest(4, 1, true, manager); List peers = new ArrayList(3); peers.add(p1); peers.add(p2); peers.add(p3); // Test simple round robin (all weight = 1) assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); // Test weighted round robin (p1=2, p2=1, p3=1) p1.setRating(2); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); // Test weighted round robin (p1=2, p2=2, p3=1) p2.setRating(2); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); // Test equally weighted round robin (p1=2, p2=2, p3=2) p3.setRating(2); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); // Add Peer-4 with weight 1 to list peers.add(p4); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); // expected glitch here: due to the sudden availibity of Peer-4, the algorithm is disturbed assertEquals(p4.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p4.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); assertEquals(p4.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p3.toString(), router.selectPeer(peers).toString()); // Next cycle would produce Peer-4, but reduce peer list now peers = peers.subList(0, 2); // now: Peer-1, Peer-2 assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); } @Test public void testWeightedLeastConnections() throws Exception { Configuration config = new XMLConfiguration("src/test/resources/jdiameter-weightedleastconnections-config.xml"); WeightedLeastConnectionsRouter router = new WeightedLeastConnectionsRouter(new RealmTableTest(), config); IStatisticManager manager = new StatisticManagerImpl(config); PeerTest p1 = new PeerTest(1, 1, true, manager); PeerTest p2 = new PeerTest(2, 1, true, manager); PeerTest p3 = new PeerTest(3, 1, true, manager); List peers = new ArrayList(2); peers.add(p1); peers.add(p2); // Test simple round robin (all weight = 1) assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); // increase p1 requests/s by 1 p1.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRequestPerSecond.name() + '.' + p1.getUri()).inc(); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); // increase p2 requests/s by 1 p2.getStatistic().getRecordByName(IStatisticRecord.Counters.NetGenRequestPerSecond.name() + '.' + p2.getUri()).inc(); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); // decrease p1 requests/s by 1 p1.getStatistic().getRecordByName(IStatisticRecord.Counters.NetGenResponsePerSecond.name() + '.' + p1.getUri()).dec(); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); // increase p1 requests/s by 3 p1.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRequestPerSecond.name() + '.' + p1.getUri()).inc(); p1.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRequestPerSecond.name() + '.' + p1.getUri()).inc(); p1.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRequestPerSecond.name() + '.' + p1.getUri()).inc(); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); // increase p2 requests/s by 1 p2.getStatistic().getRecordByName(IStatisticRecord.Counters.NetGenRequestPerSecond.name() + '.' + p2.getUri()).inc(); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); // increase weight of p1 p1.setRating(2); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); // decrease p1 requests/s by 1 p1.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRequestPerSecond.name() + '.' + p1.getUri()).dec(); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); // increase p1 requests/s by 2 p1.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRequestPerSecond.name() + '.' + p1.getUri()).inc(); p1.getStatistic().getRecordByName(IStatisticRecord.Counters.AppGenRequestPerSecond.name() + '.' + p1.getUri()).inc(); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); // increase weight and requests/s of p2 p2.setRating(2); p2.getStatistic().getRecordByName(IStatisticRecord.Counters.NetGenRequestPerSecond.name() + '.' + p2.getUri()).inc(); p2.getStatistic().getRecordByName(IStatisticRecord.Counters.NetGenRequestPerSecond.name() + '.' + p2.getUri()).inc(); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); assertEquals(p2.toString(), router.selectPeer(peers).toString()); // increase p2 requests/s by 1 p2.getStatistic().getRecordByName(IStatisticRecord.Counters.NetGenRequestPerSecond.name() + '.' + p2.getUri()).inc(); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); assertEquals(p1.toString(), router.selectPeer(peers).toString()); } private static class RealmTableTest implements IRealmTable { public Realm matchRealm(IRequest request) { return null; } public Realm matchRealm(IAnswer message, String destRealm) { return null; } public Realm getRealm(String realmName, ApplicationId applicationId) { return null; } public Realm removeRealmApplicationId(String realmName, ApplicationId appId) { return null; } public Collection removeRealm(String realmName) { return null; } public Collection getRealms(String realm) { return null; } public Collection getRealms() { return null; } public String getRealmForPeer(String fqdn) { return null; } public void addLocalApplicationId(ApplicationId ap) { } public void removeLocalApplicationId(ApplicationId a) { } public void addLocalRealm(String localRealm, String fqdn) { } public Realm addRealm(String name, ApplicationId appId, LocalAction locAction, IAgentConfiguration agentConfImpl, boolean isDynamic, long expirationTime, String[] hosts) throws InternalException { return null; } public Statistic getStatistic(String realmName) { return null; } public Realm addRealm(String realmName, ApplicationId applicationId, LocalAction action, String agentConfiguration, boolean dynamic, long expirationTime, String[] hosts) throws InternalException { return null; } public boolean realmExists(String realmName) { return false; } public boolean isWrapperFor(Class iface) throws InternalException { return false; } public T unwrap(Class iface) throws InternalException { return null; } public List getAllRealmSet() { return null; } } private static class PeerTest extends AbstractPeer implements IPeer { private int id; private int rating; private boolean connected; public PeerTest(int id, int rating, boolean connected, IStatisticManager manager) throws URISyntaxException, UnknownServiceException { super(new URI("aaa://" + id), manager); this.id = id; this.rating = rating; this.connected = connected; createPeerStatistics(); } public void setRating(int rating) { this.rating = rating; } public int getRating() { return rating; } public long getHopByHopIdentifier() { return 0; } public void addMessage(IMessage message) { } public void remMessage(IMessage message) { } public IMessage[] remAllMessage() { return new IMessage[0]; } public boolean handleMessage(EventTypes type, IMessage message, String key) throws TransportException, OverloadException, InternalException { return false; } public boolean sendMessage(IMessage message) throws TransportException, OverloadException, InternalException { return false; } public boolean hasValidConnection() { return connected; } public void setRealm(String realm) { } public void addStateChangeListener(StateChangeListener listener) { } public void remStateChangeListener(StateChangeListener listener) { } public void addConnectionListener(IConnectionListener listener) { } public void remConnectionListener(IConnectionListener listener) { } public IStatistic getStatistic() { return statistic; } public boolean isConnected() { return connected; } public void connect() throws InternalException, IOException, IllegalDiameterStateException { } @Override public void disconnect(int disconnectCause) throws InternalException, IllegalDiameterStateException { } public E getState(Class enumc) { return null; } public URI getUri() { return uri; } public InetAddress[] getIPAddresses() { return new InetAddress[0]; } public String getRealmName() { return null; } public long getVendorId() { return 0; } public String getProductName() { return null; } public long getFirmware() { return 0; } public Set getCommonApplications() { return null; } public void addPeerStateListener(PeerStateListener listener) { } public void removePeerStateListener(PeerStateListener listener) { } @Override public String toString() { return "Peer-" + id; } } } ================================================ FILE: core/jdiameter/impl/src/test/resources/jdiameter-weightedleastconnections-config.xml ================================================ ================================================ FILE: core/jdiameter/impl/src/test/resources/jdiameter-weightedroundrobin-config.xml ================================================ ================================================ FILE: core/jdiameter/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter diameter-core-parent 2.5.1-SNAPSHOT ../pom.xml jdiameter-core pom Quarkus :: JDiameter Stack :: Parent api impl ================================================ FILE: core/jdiameter-ha/api/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter jdiameter-ha-parent 2.5.1-SNAPSHOT ../pom.xml jdiameter-ha-api Quarkus :: JDiameter Stack HA :: Api io.quarkiverse.jdiameter jdiameter-api ================================================ FILE: core/jdiameter-ha/api/src/main/java/org/jdiameter/api/ha/data/CachingException.java ================================================ package org.jdiameter.api.ha.data; public class CachingException extends RuntimeException { public CachingException(String message, Throwable cause) { super(message, cause); } } ================================================ FILE: core/jdiameter-ha/impl/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter jdiameter-ha-parent 2.5.1-SNAPSHOT ../pom.xml jdiameter-ha-impl Quarkus :: JDiameter Stack HA :: Impl ${project.groupId} jdiameter-ha-api ${project.version} io.quarkiverse.jdiameter jdiameter-impl io.quarkus quarkus-infinispan-client ${quarkus.version} provided com.fasterxml.jackson.core jackson-databind provided com.fasterxml.jackson.datatype jackson-datatype-jsr310 provided ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/acc/ClientAccSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.client.acc; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.acc.ClientAccSession; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.client.impl.app.acc.IClientAccSessionData; import org.jdiameter.common.api.app.acc.ClientAccSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.nio.ByteBuffer; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ClientAccSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IClientAccSessionData { private static final Logger logger = LoggerFactory.getLogger(ClientAccSessionDataReplicatedImpl.class); private static final String STATE = "STATE"; private static final String INTERIM_TIMERID = "INTERIM_TIMERID"; private static final String DEST_HOST = "DEST_HOST"; private static final String DEST_REALM = "DEST_REALM"; private static final String BUFFER = "BUFFER"; private final IMessageParser messageParser; public ClientAccSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientAccSession.class); this.messageParser = datasource.getContainer().getAssemblerFacility().getComponentInstance(IMessageParser.class); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.acc.IClientAccSessionData#setClientAccSessionState * (org.jdiameter.common.api.app.acc.ClientAccSessionState) */ @Override public void setClientAccSessionState(ClientAccSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.acc.IClientAccSessionData#getClientAccSessionState() */ @Override public ClientAccSessionState getClientAccSessionState() { return ClientAccSessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.acc.IClientAccSessionData#setInterimTimerId(java.io.Serializable) */ @Override public void setInterimTimerId(Serializable tid) { setFieldValue(INTERIM_TIMERID, tid); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.acc.IClientAccSessionData#getInterimTimerId() */ @Override public Serializable getInterimTimerId() { return getFieldValue(INTERIM_TIMERID); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.acc.IClientAccSessionData#setDestinationHost(java.lang.String) */ @Override public void setDestinationHost(String destHost) { setFieldValue(DEST_HOST, destHost); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.acc.IClientAccSessionData#getDestinationHost() */ @Override public String getDestinationHost() { return getFieldValue(DEST_HOST); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.acc.IClientAccSessionData#setDestinationRealm(java.lang.String) */ @Override public void setDestinationRealm(String destRealm) { setFieldValue(DEST_REALM, destRealm); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.acc.IClientAccSessionData#getDestinationRealm() */ @Override public String getDestinationRealm() { return getFieldValue(DEST_REALM); } @Override public Request getBuffer() { byte[] data = getFieldValue(BUFFER); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate message from buffer."); return null; } } else { return null; } } @Override public void setBuffer(Request buffer) { if (buffer != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) buffer).array(); setFieldValue(BUFFER, data); } catch (ParseException e) { logger.error("Unable to encode message to buffer."); } } else { remove(BUFFER); } } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/auth/ClientAuthSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.client.auth; import org.jdiameter.api.auth.ClientAuthSession; import org.jdiameter.client.impl.app.auth.IClientAuthSessionData; import org.jdiameter.common.api.app.auth.ClientAuthSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import java.io.Serializable; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ClientAuthSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IClientAuthSessionData { private static final String STATE = "STATE"; private static final String DESTINATION_HOST = "DESTINATION_HOST"; private static final String DESTINATION_REALM = "DESTINATION_REALM"; private static final String STATELESS = "STATELESS"; private static final String TS_TIMERID = "TS_TIMERID"; public ClientAuthSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientAuthSession.class); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setClientAuthSessionState(org.jdiameter.common.api.app.auth. * ClientAuthSessionState) */ @Override public void setClientAuthSessionState(ClientAuthSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#getClientAuthSessionState() */ @Override public ClientAuthSessionState getClientAuthSessionState() { return ClientAuthSessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#isStateless() */ @Override public boolean isStateless() { return toPrimitive(getFieldValue(STATELESS), true); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setStateless(boolean) */ @Override public void setStateless(boolean b) { setFieldValue(STATELESS, b); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#getDestinationHost() */ @Override public String getDestinationHost() { return getFieldValue(DESTINATION_HOST); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setDestinationHost(java.lang.String) */ @Override public void setDestinationHost(String host) { setFieldValue(DESTINATION_HOST, host); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#getDestinationRealm() */ @Override public String getDestinationRealm() { return getFieldValue(DESTINATION_REALM); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setDestinationRealm(java.lang.String) */ @Override public void setDestinationRealm(String realm) { setFieldValue(DESTINATION_REALM, realm); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#getTsTimerId() */ @Override public Serializable getTsTimerId() { return getFieldValue(TS_TIMERID); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.auth.IClientAuthSessionData#setTsTimerId(java.io.Serializable) */ @Override public void setTsTimerId(Serializable tid) { setFieldValue(TS_TIMERID, tid); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/cca/ClientCCASessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.client.cca; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.cca.ClientCCASession; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.client.impl.app.cca.IClientCCASessionData; import org.jdiameter.common.api.app.cca.ClientCCASessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.nio.ByteBuffer; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ClientCCASessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IClientCCASessionData { private static final Logger logger = LoggerFactory.getLogger(ClientCCASessionDataReplicatedImpl.class); private static final String EVENT_BASED = "EVENT_BASED"; private static final String REQUEST_TYPE = "REQUEST_TYPE"; private static final String STATE = "STATE"; private static final String TXTIMER_ID = "TXTIMER_ID"; private static final String TXTIMER_REQUEST = "TXTIMER_REQUEST"; private static final String BUFFER = "BUFFER"; private static final String GRA = "GRA"; private static final String GDDFH = "GDDFH"; private static final String GCCFH = "GCCFH"; private final IMessageParser messageParser; public ClientCCASessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientCCASession.class); this.messageParser = datasource.getContainer().getAssemblerFacility().getComponentInstance(IMessageParser.class); } @Override public boolean isEventBased() { return toPrimitive(getFieldValue(EVENT_BASED), true); } @Override public void setEventBased(boolean isEventBased) { setFieldValue(EVENT_BASED, isEventBased); } @Override public boolean isRequestTypeSet() { return toPrimitive(getFieldValue(REQUEST_TYPE), false); } @Override public void setRequestTypeSet(boolean requestTypeSet) { setFieldValue(REQUEST_TYPE, requestTypeSet); } @Override public ClientCCASessionState getClientCCASessionState() { return ClientCCASessionState.valueOf(getFieldValue(STATE, "IDLE")); } @Override public void setClientCCASessionState(ClientCCASessionState state) { if (!state.name().equals(getFieldValue(STATE))) { setFieldValue(STATE, state.name()); } } @Override public Serializable getTxTimerId() { return getFieldValue(TXTIMER_ID); } @Override public void setTxTimerId(Serializable txTimerId) { setFieldValue(TXTIMER_ID, txTimerId); } @Override public Request getTxTimerRequest() { byte[] data = getByteFieldValue(TXTIMER_REQUEST); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate Tx Timer Request from buffer."); return null; } } else { return null; } } @Override public void setTxTimerRequest(Request txTimerRequest) { if (txTimerRequest != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) txTimerRequest).array(); setFieldValue(TXTIMER_REQUEST, data); } catch (ParseException e) { logger.error("Unable to encode Tx Timer Request to buffer."); } } else { remove(TXTIMER_REQUEST); } } @Override public Request getBuffer() { byte[] data = getByteFieldValue(BUFFER); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate message from buffer."); return null; } } else { return null; } } @Override public void setBuffer(Request buffer) { if (buffer != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) buffer).array(); setFieldValue(BUFFER, data); } catch (ParseException e) { logger.error("Unable to encode message to buffer."); } } else { remove(BUFFER); } } @Override public int getGatheredRequestedAction() { return toPrimitive((Integer) getFieldValue(GRA)); } @Override public void setGatheredRequestedAction(int gatheredRequestedAction) { setFieldValue(GRA, gatheredRequestedAction); } @Override public int getGatheredCCFH() { return toPrimitive((Integer) getFieldValue(GCCFH)); } @Override public void setGatheredCCFH(int gatheredCCFH) { setFieldValue(GCCFH, gatheredCCFH); } @Override public int getGatheredDDFH() { return toPrimitive((Integer) getFieldValue(GDDFH)); } @Override public void setGatheredDDFH(int gatheredDDFH) { setFieldValue(GDDFH, gatheredDDFH); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/cxdx/ClientCxDxSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.client.cxdx; import org.jdiameter.api.cxdx.ClientCxDxSession; import org.jdiameter.client.impl.app.cxdx.IClientCxDxSessionData; import org.jdiameter.impl.ha.common.cxdx.CxDxSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ClientCxDxSessionDataReplicatedImpl extends CxDxSessionDataReplicatedImpl implements IClientCxDxSessionData { public ClientCxDxSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientCxDxSession.class); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/gx/ClientGxSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.client.gx; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.gx.ClientGxSession; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.client.impl.app.gx.IClientGxSessionData; import org.jdiameter.common.api.app.gx.ClientGxSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.nio.ByteBuffer; import java.util.Base64; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ClientGxSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IClientGxSessionData { private static final Logger logger = LoggerFactory.getLogger(ClientGxSessionDataReplicatedImpl.class); private static final String EVENT_BASED = "EVENT_BASED"; private static final String REQUEST_TYPE = "REQUEST_TYPE"; private static final String STATE = "STATE"; private static final String TXTIMER_ID = "TXTIMER_ID"; private static final String TXTIMER_REQUEST = "TXTIMER_REQUEST"; private static final String BUFFER = "BUFFER"; private static final String GRA = "GRA"; private static final String GDDFH = "GDDFH"; private static final String GCCFH = "GCCFH"; private final IMessageParser messageParser; public ClientGxSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientGxSession.class); this.messageParser = datasource.getContainer().getAssemblerFacility().getComponentInstance(IMessageParser.class); } @Override public boolean isEventBased() { return toPrimitive(getFieldValue(EVENT_BASED), true); } @Override public void setEventBased(boolean isEventBased) { setFieldValue(EVENT_BASED, isEventBased); } @Override public boolean isRequestTypeSet() { return toPrimitive(getFieldValue(REQUEST_TYPE), false); } @Override public void setRequestTypeSet(boolean requestTypeSet) { setFieldValue(REQUEST_TYPE, requestTypeSet); } @Override public ClientGxSessionState getClientGxSessionState() { return ClientGxSessionState.valueOf(getFieldValue(STATE, "IDLE")); } @Override public void setClientGxSessionState(ClientGxSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } @Override public Serializable getTxTimerId() { return getFieldValue(TXTIMER_ID); } @Override public void setTxTimerId(Serializable txTimerId) { setFieldValue(TXTIMER_ID, txTimerId); } @Override public Request getTxTimerRequest() { byte[] data = Base64.getDecoder().decode((String) getFieldValue(TXTIMER_REQUEST)); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate Tx Timer Request from buffer."); return null; } } else { return null; } } @Override public void setTxTimerRequest(Request txTimerRequest) { if (txTimerRequest != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) txTimerRequest).array(); setFieldValue(TXTIMER_REQUEST, Base64.getEncoder().encode(data)); } catch (ParseException e) { logger.error("Unable to encode Tx Timer Request to buffer."); } } else { remove(TXTIMER_REQUEST); } } @Override public Request getBuffer() { byte[] data = getByteFieldValue(BUFFER); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate message from buffer."); return null; } } else { return null; } } @Override public void setBuffer(Request buffer) { if (buffer != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) buffer).array(); setFieldValue(BUFFER, data); } catch (ParseException e) { logger.error("Unable to encode message to buffer."); } } else { remove(BUFFER); } } @Override public int getGatheredRequestedAction() { return toPrimitive((Integer) getFieldValue(GRA)); } @Override public void setGatheredRequestedAction(int gatheredRequestedAction) { setFieldValue(GRA, gatheredRequestedAction); } @Override public int getGatheredCCFH() { return toPrimitive((Integer) getFieldValue(GCCFH)); } @Override public void setGatheredCCFH(int gatheredCCFH) { setFieldValue(GCCFH, gatheredCCFH); } @Override public int getGatheredDDFH() { return toPrimitive((Integer) getFieldValue(GDDFH)); } @Override public void setGatheredDDFH(int gatheredDDFH) { setFieldValue(GDDFH, gatheredDDFH); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/rf/ClientRfSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.client.rf; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.rf.ClientRfSession; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.client.impl.app.rf.IClientRfSessionData; import org.jdiameter.common.api.app.rf.ClientRfSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.nio.ByteBuffer; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ClientRfSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IClientRfSessionData { private static final Logger logger = LoggerFactory.getLogger(ClientRfSessionDataReplicatedImpl.class); private static final String STATE = "STATE"; private static final String BUFFER = "BUFFER"; private static final String TS_TIMERID = "TS_TIMERID"; private static final String DESTINATION_HOST = "DESTINATION_HOST"; private static final String DESTINATION_REALM = "DESTINATION_REALM"; private final IMessageParser messageParser; public ClientRfSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientRfSession.class); this.messageParser = datasource.getContainer().getAssemblerFacility().getComponentInstance(IMessageParser.class); } @Override public ClientRfSessionState getClientRfSessionState() { return ClientRfSessionState.valueOf(getFieldValue(STATE, "IDLE")); } @Override public void setClientRfSessionState(ClientRfSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } @Override public Request getBuffer() { byte[] data = getByteFieldValue(BUFFER); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate message from buffer."); return null; } } else { return null; } } @Override public void setBuffer(Request buffer) { if (buffer != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) buffer).array(); setFieldValue(BUFFER, data); } catch (ParseException e) { logger.error("Unable to encode message to buffer."); } } else { remove(BUFFER); } } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#getTsTimerId() */ @Override public Serializable getTsTimerId() { return getFieldValue(TS_TIMERID); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#setTsTimerId(java.io.Serializable) */ @Override public void setTsTimerId(Serializable tid) { setFieldValue(TS_TIMERID, tid); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#getDestinationHost() */ @Override public String getDestinationHost() { return getFieldValue(DESTINATION_HOST); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#setDestinationHost(java.lang.String) */ @Override public void setDestinationHost(String destinationHost) { setFieldValue(DESTINATION_HOST, destinationHost); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#getDestinationRealm() */ @Override public String getDestinationRealm() { return getFieldValue(DESTINATION_REALM); } /* * (non-Javadoc) * * @see org.jdiameter.client.impl.app.rf.IClientRfSessionData#setDestinationRealm(java.lang.String) */ @Override public void setDestinationRealm(String destinationRealm) { setFieldValue(DESTINATION_REALM, destinationRealm); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/ro/ClientRoSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.client.ro; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.api.ro.ClientRoSession; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.client.impl.app.ro.IClientRoSessionData; import org.jdiameter.common.api.app.ro.ClientRoSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.nio.ByteBuffer; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ClientRoSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IClientRoSessionData { private static final Logger logger = LoggerFactory.getLogger(ClientRoSessionDataReplicatedImpl.class); private static final String EVENT_BASED = "EVENT_BASED"; private static final String REQUEST_TYPE = "REQUEST_TYPE"; private static final String STATE = "STATE"; private static final String TXTIMER_ID = "TXTIMER_ID"; private static final String TXTIMER_REQUEST = "TXTIMER_REQUEST"; private static final String BUFFER = "BUFFER"; private static final String GRA = "GRA"; private static final String GDDFH = "GDDFH"; private static final String GCCFH = "GCCFH"; private final IMessageParser messageParser; public ClientRoSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientRoSession.class); this.messageParser = datasource.getContainer().getAssemblerFacility().getComponentInstance(IMessageParser.class); } @Override public boolean isEventBased() { return toPrimitive(getFieldValue(EVENT_BASED), true); } @Override public void setEventBased(boolean isEventBased) { setFieldValue(EVENT_BASED, isEventBased); } @Override public boolean isRequestTypeSet() { return toPrimitive(getFieldValue(REQUEST_TYPE), false); } @Override public void setRequestTypeSet(boolean requestTypeSet) { setFieldValue(REQUEST_TYPE, requestTypeSet); } @Override public ClientRoSessionState getClientRoSessionState() { return ClientRoSessionState.valueOf(getFieldValue(STATE, "IDLE")); } @Override public void setClientRoSessionState(ClientRoSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } @Override public Serializable getTxTimerId() { return getFieldValue(TXTIMER_ID); } @Override public void setTxTimerId(Serializable txTimerId) { setFieldValue(TXTIMER_ID, txTimerId); } @Override public Request getTxTimerRequest() { byte[] data = getFieldValue(TXTIMER_REQUEST); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate Tx Timer Request from buffer."); return null; } } else { return null; } } @Override public void setTxTimerRequest(Request txTimerRequest) { if (txTimerRequest != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) txTimerRequest).array(); setFieldValue(TXTIMER_REQUEST, data); } catch (ParseException e) { logger.error("Unable to encode Tx Timer Request to buffer."); } } else { remove(TXTIMER_REQUEST); } } @Override public Request getBuffer() { byte[] data = getFieldValue(BUFFER); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate message from buffer."); return null; } } else { return null; } } @Override public void setBuffer(Request buffer) { if (buffer != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) buffer).array(); setFieldValue(BUFFER, data); } catch (ParseException e) { logger.error("Unable to encode message to buffer."); } } else { remove(BUFFER); } } @Override public int getGatheredRequestedAction() { return toPrimitive((Integer) getFieldValue(GRA)); } @Override public void setGatheredRequestedAction(int gatheredRequestedAction) { setFieldValue(GRA, gatheredRequestedAction); } @Override public int getGatheredCCFH() { return toPrimitive((Integer) getFieldValue(GCCFH)); } @Override public void setGatheredCCFH(int gatheredCCFH) { setFieldValue(GCCFH, gatheredCCFH); } @Override public int getGatheredDDFH() { return toPrimitive((Integer) getFieldValue(GDDFH)); } @Override public void setGatheredDDFH(int gatheredDDFH) { setFieldValue(GDDFH, gatheredDDFH); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/rx/ClientRxSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.client.rx; import org.jdiameter.api.rx.ClientRxSession; import org.jdiameter.client.impl.app.rx.IClientRxSessionData; import org.jdiameter.common.api.app.rx.ClientRxSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ClientRxSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IClientRxSessionData { private static final String EVENT_BASED = "EVENT_BASED"; private static final String REQUEST_TYPE = "REQUEST_TYPE"; private static final String STATE = "STATE"; public ClientRxSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientRxSession.class); } @Override public boolean isEventBased() { return toPrimitive(getFieldValue(EVENT_BASED), true); } @Override public void setEventBased(boolean isEventBased) { setFieldValue(EVENT_BASED, isEventBased); } @Override public boolean isRequestTypeSet() { return toPrimitive(getFieldValue(REQUEST_TYPE), false); } @Override public void setRequestTypeSet(boolean requestTypeSet) { setFieldValue(REQUEST_TYPE, requestTypeSet); } @Override public ClientRxSessionState getClientRxSessionState() { return ClientRxSessionState.valueOf(getFieldValue(STATE, "IDLE")); } @Override public void setClientRxSessionState(ClientRxSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/s13/ClientS13SessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.impl.ha.client.s13; import org.jdiameter.api.s13.ClientS13Session; import org.jdiameter.client.impl.app.s13.IClientS13SessionData; import org.jdiameter.impl.ha.common.s13.S13SessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ClientS13SessionDataReplicatedImpl extends S13SessionDataReplicatedImpl implements IClientS13SessionData { public ClientS13SessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientS13Session.class); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/client/sh/ShClientSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.client.sh; import org.jdiameter.api.sh.ClientShSession; import org.jdiameter.client.impl.app.sh.IShClientSessionData; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ShClientSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IShClientSessionData { public ShClientSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ClientShSession.class); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/AppSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.app.AppSession; import org.jdiameter.common.api.app.IAppSessionData; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import java.util.Base64; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class AppSessionDataReplicatedImpl implements IAppSessionData { protected static final String APID = "APID"; public static final String SIFACE = "SIFACE"; private final CachedSessionDatasource datasource; private final String sessionId; public AppSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { this.sessionId = sessionId; this.datasource = datasource; } public void setAppSessionIface(Class iface) { if (datasource.getFieldValue(sessionId, SIFACE) == null) { datasource.setFieldValue(sessionId, SIFACE, iface.getCanonicalName()); } } @Override public String getSessionId() { return sessionId; } @Override public void setApplicationId(ApplicationId applicationId) { datasource.setFieldValue(sessionId, APID, applicationId.getVendorId() + ":" + applicationId.getAcctAppId() + ":" + applicationId.getAuthAppId()); } @Override public ApplicationId getApplicationId() { String appIdStr = datasource.getFieldValue(sessionId, APID); if (appIdStr == null) { throw new IllegalArgumentException("The ApplicationId field is unexpectedly NULL"); } String[] app = appIdStr.split(":"); long venId = Long.parseLong(app[0]); long authId = Long.parseLong(app[1]); long acctId = Long.parseLong(app[2]); if (acctId == 0) { return ApplicationId.createByAuthAppId(venId, authId); }//if else { return ApplicationId.createByAccAppId(venId, acctId); }//else } @Override public boolean remove() { datasource.removeSession(sessionId); return true; } public T getFieldValue(String fieldName, T defaultValue) { T val = datasource.getFieldValue(sessionId, fieldName); if (val == null) { return defaultValue; } return val; }//getFieldValue public T getFieldValue(String fieldName) { return datasource.getFieldValue(sessionId, fieldName); }//getFieldValue public byte[] getByteFieldValue(String fieldName) { String value = getFieldValue(fieldName); if (value == null) { return null; } return Base64.getDecoder().decode(value); } public void setFieldValue(String fieldName, byte[] value) { datasource.setFieldValue(sessionId, fieldName, Base64.getEncoder().encodeToString(value)); }//setFieldValue public void setFieldValue(String fieldName, Object value) { datasource.setFieldValue(sessionId, fieldName, value); }//setFieldValue public void remove(String fieldName) { datasource.setFieldValue(sessionId, fieldName, null); } public CachedSessionDatasource getDatasource() { return datasource; } protected boolean toPrimitive(Boolean b, boolean _default) { return b == null ? _default : b; } protected int toPrimitive(Integer i) { return i == null ? NON_INITIALIZED : i; } protected long toPrimitive(Long l) { return l == null ? NON_INITIALIZED : l; } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/acc/AccReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.acc; import org.jdiameter.api.acc.ClientAccSession; import org.jdiameter.api.acc.ServerAccSession; import org.jdiameter.api.app.AppSession; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.acc.IAccSessionData; import org.jdiameter.impl.ha.client.acc.ClientAccSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.acc.ServerAccSessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class AccReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public AccReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IAccSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientAccSession.class)) { ClientAccSessionDataReplicatedImpl data = new ClientAccSessionDataReplicatedImpl(sessionId, this.cachedSessionDataSource); return data; } else if (clazz.equals(ServerAccSession.class)) { ServerAccSessionDataReplicatedImpl data = new ServerAccSessionDataReplicatedImpl(sessionId, this.cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/auth/AuthReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.auth; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.ClientAuthSession; import org.jdiameter.api.auth.ServerAuthSession; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.auth.IAuthSessionData; import org.jdiameter.impl.ha.client.auth.ClientAuthSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.auth.ServerAuthSessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class AuthReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public AuthReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IAuthSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientAuthSession.class)) { ClientAuthSessionDataReplicatedImpl data = new ClientAuthSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } else if (clazz.equals(ServerAuthSession.class)) { ServerAuthSessionDataReplicatedImpl data = new ServerAuthSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/cca/CCAReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.cca; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.cca.ClientCCASession; import org.jdiameter.api.cca.ServerCCASession; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.cca.ICCASessionData; import org.jdiameter.impl.ha.client.cca.ClientCCASessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.cca.ServerCCASessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class CCAReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public CCAReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public ICCASessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientCCASession.class)) { ClientCCASessionDataReplicatedImpl data = new ClientCCASessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } else if (clazz.equals(ServerCCASession.class)) { ServerCCASessionDataReplicatedImpl data = new ServerCCASessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/cxdx/CxDxReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.cxdx; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.cxdx.ClientCxDxSession; import org.jdiameter.api.cxdx.ServerCxDxSession; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; import org.jdiameter.impl.ha.client.cxdx.ClientCxDxSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.cxdx.ServerCxDxSessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class CxDxReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public CxDxReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public ICxDxSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientCxDxSession.class)) { ClientCxDxSessionDataReplicatedImpl data = new ClientCxDxSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } else if (clazz.equals(ServerCxDxSession.class)) { ServerCxDxSessionDataReplicatedImpl data = new ServerCxDxSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/cxdx/CxDxSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.cxdx; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.common.api.app.cxdx.CxDxSessionState; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.nio.ByteBuffer; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public abstract class CxDxSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements ICxDxSessionData { private static final Logger logger = LoggerFactory.getLogger(CxDxSessionDataReplicatedImpl.class); private static final String STATE = "STATE"; private static final String BUFFER = "BUFFER"; private static final String TS_TIMERID = "TS_TIMERID"; private final IMessageParser messageParser; public CxDxSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); this.messageParser = datasource.getContainer().getAssemblerFacility().getComponentInstance(IMessageParser.class); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#setCxDxSessionState(org.jdiameter.common.api.app.cxdx.CxDxSessionState) */ @Override public void setCxDxSessionState(CxDxSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#getCxDxSessionState() */ @Override public CxDxSessionState getCxDxSessionState() { return CxDxSessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#getTsTimerId() */ @Override public Serializable getTsTimerId() { return getFieldValue(TS_TIMERID); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.cxdx.ICxDxSessionData#setTsTimerId(java.io.Serializable) */ @Override public void setTsTimerId(Serializable tid) { setFieldValue(TS_TIMERID, tid); } @Override public Request getBuffer() { byte[] data = getByteFieldValue(BUFFER); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate message from buffer."); return null; } } else { return null; } } @Override public void setBuffer(Request buffer) { if (buffer != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) buffer).array(); setFieldValue(BUFFER, data); } catch (ParseException e) { logger.error("Unable to encode message to buffer."); } } else { remove(BUFFER); } } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/gx/GxReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.gx; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.gx.ClientGxSession; import org.jdiameter.api.gx.ServerGxSession; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.gx.IGxSessionData; import org.jdiameter.impl.ha.client.gx.ClientGxSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.gx.ServerGxSessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class GxReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public GxReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IGxSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientGxSession.class)) { ClientGxSessionDataReplicatedImpl data = new ClientGxSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } else if (clazz.equals(ServerGxSession.class)) { ServerGxSessionDataReplicatedImpl data = new ServerGxSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/rf/RfReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.rf; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rf.ClientRfSession; import org.jdiameter.api.rf.ServerRfSession; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.rf.IRfSessionData; import org.jdiameter.impl.ha.client.rf.ClientRfSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.rf.ServerRfSessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class RfReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public RfReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IRfSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientRfSession.class)) { ClientRfSessionDataReplicatedImpl data = new ClientRfSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } else if (clazz.equals(ServerRfSession.class)) { ServerRfSessionDataReplicatedImpl data = new ServerRfSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/ro/RoReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.ro; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.ro.ClientRoSession; import org.jdiameter.api.ro.ServerRoSession; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.ro.IRoSessionData; import org.jdiameter.impl.ha.client.ro.ClientRoSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.ro.ServerRoSessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class RoReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public RoReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IRoSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientRoSession.class)) { ClientRoSessionDataReplicatedImpl data = new ClientRoSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } else if (clazz.equals(ServerRoSession.class)) { ServerRoSessionDataReplicatedImpl data = new ServerRoSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/rx/RxReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.rx; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.rx.ClientRxSession; import org.jdiameter.api.rx.ServerRxSession; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.rx.IRxSessionData; import org.jdiameter.impl.ha.client.rx.ClientRxSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.rx.ServerRxSessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class RxReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public RxReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IRxSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientRxSession.class)) { ClientRxSessionDataReplicatedImpl data = new ClientRxSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } else if (clazz.equals(ServerRxSession.class)) { ServerRxSessionDataReplicatedImpl data = new ServerRxSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/s13/S13ReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.impl.ha.common.s13; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.s13.ClientS13Session; import org.jdiameter.api.s13.ServerS13Session; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.impl.ha.client.s13.ClientS13SessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.s13.ServerS13SessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class S13ReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public S13ReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) */ @Override public IS13SessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientS13Session.class)) { ClientS13SessionDataReplicatedImpl data = new ClientS13SessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } else if (clazz.equals(ServerS13Session.class)) { ServerS13SessionDataReplicatedImpl data = new ServerS13SessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/s13/S13SessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.impl.ha.common.s13; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Request; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.api.parser.ParseException; import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.common.api.app.s13.S13SessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.nio.ByteBuffer; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public abstract class S13SessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IS13SessionData { private static final Logger logger = LoggerFactory.getLogger(S13SessionDataReplicatedImpl.class); private static final String STATE = "STATE"; private static final String BUFFER = "BUFFER"; private static final String TS_TIMERID = "TS_TIMERID"; private final IMessageParser messageParser; public S13SessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); this.messageParser = datasource.getContainer().getAssemblerFacility().getComponentInstance(IMessageParser.class); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.s13.IS13SessionData#setS13SessionState(org.jdiameter.common.api.app.s13.S13SessionState) */ @Override public void setS13SessionState(S13SessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.s13.IS13SessionData#getS13SessionState() */ @Override public S13SessionState getS13SessionState() { return S13SessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.s13.IS13SessionData#getTsTimerId() */ @Override public Serializable getTsTimerId() { return getFieldValue(TS_TIMERID); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.s13.IS13SessionData#setTsTimerId(java.io.Serializable) */ @Override public void setTsTimerId(Serializable tid) { setFieldValue(TS_TIMERID, tid); } @Override public Request getBuffer() { byte[] data = getByteFieldValue(BUFFER); if (data != null) { try { return this.messageParser.createMessage(ByteBuffer.wrap(data)); } catch (AvpDataException e) { logger.error("Unable to recreate message from buffer."); return null; } } else { return null; } } @Override public void setBuffer(Request buffer) { if (buffer != null) { try { byte[] data = this.messageParser.encodeMessage((IMessage) buffer).array(); setFieldValue(BUFFER, data); } catch (ParseException e) { logger.error("Unable to encode message to buffer."); } } else { remove(BUFFER); } } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/common/sh/ShReplicatedSessionDataFactory.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.common.sh; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.sh.ClientShSession; import org.jdiameter.api.sh.ServerShSession; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.sh.IShSessionData; import org.jdiameter.impl.ha.client.sh.ShClientSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.impl.ha.server.sh.ShServerSessionDataReplicatedImpl; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ShReplicatedSessionDataFactory implements IAppSessionDataFactory { private final CachedSessionDatasource cachedSessionDataSource; public ShReplicatedSessionDataFactory(CachedSessionDatasource replicatedSessionDataSource) { // Is this ok? super(); this.cachedSessionDataSource = replicatedSessionDataSource; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData (java.lang.Class, java.lang.String) */ @Override public IShSessionData getAppSessionData(Class clazz, String sessionId) { if (clazz.equals(ClientShSession.class)) { ShClientSessionDataReplicatedImpl data = new ShClientSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } else if (clazz.equals(ServerShSession.class)) { ShServerSessionDataReplicatedImpl data = new ShServerSessionDataReplicatedImpl(sessionId, cachedSessionDataSource); return data; } throw new IllegalArgumentException(); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/data/CachedSessionDatasource.java ================================================ package org.jdiameter.impl.ha.data; import org.infinispan.client.hotrod.RemoteCache; import org.jdiameter.client.api.IContainer; public interface CachedSessionDatasource { RemoteCache getDataCache(); IContainer getContainer(); T getFieldValue(String sessionId, String fieldName); void setFieldValue(String sessionId, String fieldName, Object value); void removeSession(String sessionId); } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/data/CachedSessionDatasourceImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.data; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.quarkus.arc.Arc; import io.quarkus.arc.InstanceHandle; import io.quarkus.infinispan.client.runtime.InfinispanClientProducer; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; import org.jdiameter.api.BaseSession; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.ha.data.CachingException; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.IAppSessionFactory; import org.jdiameter.common.api.app.acc.IAccSessionData; import org.jdiameter.common.api.app.auth.IAuthSessionData; import org.jdiameter.common.api.app.cca.ICCASessionData; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; import org.jdiameter.common.api.app.gx.IGxSessionData; import org.jdiameter.common.api.app.rf.IRfSessionData; import org.jdiameter.common.api.app.ro.IRoSessionData; import org.jdiameter.common.api.app.rx.IRxSessionData; import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.common.api.app.sh.IShSessionData; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.common.acc.AccReplicatedSessionDataFactory; import org.jdiameter.impl.ha.common.auth.AuthReplicatedSessionDataFactory; import org.jdiameter.impl.ha.common.cca.CCAReplicatedSessionDataFactory; import org.jdiameter.impl.ha.common.cxdx.CxDxReplicatedSessionDataFactory; import org.jdiameter.impl.ha.common.gx.GxReplicatedSessionDataFactory; import org.jdiameter.impl.ha.common.rf.RfReplicatedSessionDataFactory; import org.jdiameter.impl.ha.common.ro.RoReplicatedSessionDataFactory; import org.jdiameter.impl.ha.common.rx.RxReplicatedSessionDataFactory; import org.jdiameter.impl.ha.common.s13.S13ReplicatedSessionDataFactory; import org.jdiameter.impl.ha.common.sh.ShReplicatedSessionDataFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import static org.jdiameter.server.impl.helpers.Parameters.CachingName; /** * Replicated datasource implementation for {@link ISessionDatasource} * * @author Alexandre Mendonca * @author Bartosz Baranowski */ public class CachedSessionDatasourceImpl implements ISessionDatasource, CachedSessionDatasource { private static class SessionEntry { private final BaseSession session; private NetworkReqListener listener; public SessionEntry(BaseSession session) { this.session = session; listener = null; } public SessionEntry(BaseSession session, NetworkReqListener listener) { this.session = session; this.listener = listener; } public NetworkReqListener getListener() { return listener; } public NetworkReqListener setListener(NetworkReqListener listener) { NetworkReqListener prev = this.listener; this.listener = listener; return prev; } public BaseSession getSession() { return session; } @Override public String toString() { return "SessionEntry [session=" + session + ", listener=" + listener + "]"; } } private static final Logger logger = LoggerFactory.getLogger(CachedSessionDatasourceImpl.class); private final IContainer container; private final Map sessions = new ConcurrentHashMap<>(); private final RemoteCache dataSessions; private final ObjectMapper mapper; // provided by impl, no way to change that, no conf! :) protected HashMap, IAppSessionDataFactory> appSessionDataFactories = new HashMap<>(); public CachedSessionDatasourceImpl(IContainer container) { String cachingName = container.getConfiguration().getStringValue(CachingName.ordinal(), (String) CachingName.defValue()); RemoteCacheManager remoteCacheManager = null; InstanceHandle infinispanClientProducer = Arc.container().instance(InfinispanClientProducer.class); if (infinispanClientProducer.isAvailable()) { remoteCacheManager = infinispanClientProducer.get().getNamedRemoteCacheManager(""); }//if if (remoteCacheManager == null || !remoteCacheManager.isStarted()) { throw new RuntimeException("Error loading cache provider"); }//if dataSessions = remoteCacheManager.getCache(cachingName); mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.registerModule(new JavaTimeModule()); this.container = container; // this is coded, its tied to specific impl of SessionDatasource appSessionDataFactories.put(IAuthSessionData.class, new AuthReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IAccSessionData.class, new AccReplicatedSessionDataFactory(this)); appSessionDataFactories.put(ICCASessionData.class, new CCAReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IRoSessionData.class, new RoReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IRfSessionData.class, new RfReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IShSessionData.class, new ShReplicatedSessionDataFactory(this)); appSessionDataFactories.put(ICxDxSessionData.class, new CxDxReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IGxSessionData.class, new GxReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IRxSessionData.class, new RxReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IS13SessionData.class, new S13ReplicatedSessionDataFactory(this)); } @Override public RemoteCache getDataCache() { return dataSessions; } @Override public boolean exists(String sessionId) { return sessions.get(sessionId) != null || dataSessions.get(sessionId) != null; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.ha.ISessionDatasource#addSession(org.jdiameter .api.BaseSession) */ @Override public void addSession(BaseSession session) { // Simple as is, if its replicated, it will be already there :-) sessions.put(session.getSessionId(), new SessionEntry(session)); logger.debug("{}: Added session. Flushed local cache", session.getSessionId()); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.ha.ISessionDatasource#getSession(java.lang.String ) */ @Override public BaseSession getSession(String sessionId) { SessionEntry session = sessions.get(sessionId); if (session == null && dataSessions.get(sessionId) != null) { session = this.loadCachedSession(sessionId); } if (session != null) { return session.getSession(); } return null; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.ha.ISessionDatasource#getSessionListener(java .lang.String) */ @Override public NetworkReqListener getSessionListener(String sessionId) { SessionEntry session = sessions.get(sessionId); if (session != null) { return session.getListener(); } return null; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.ha.ISessionDatasource#removeSession(java.lang .String) */ @Override public void removeSession(String sessionId) { logger.debug("removeSession({}) from the cache", sessionId); sessions.remove(sessionId); dataSessions.remove(sessionId); } /* * (non-Javadoc) * * @see org.jdiameter.common.api.ha.ISessionDatasource#removeSessionListener( java.lang.String) */ @Override public NetworkReqListener removeSessionListener(String sessionId) { SessionEntry session = sessions.get(sessionId); if (session != null) { return session.setListener(null); } return null; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.ha.ISessionDatasource#setSessionListener(java .lang.String, org.jdiameter.api.NetworkReqListener) */ @Override public void setSessionListener(String sessionId, NetworkReqListener listener) { SessionEntry session = sessions.get(sessionId); if (session == null && dataSessions.get(sessionId) != null) { session = this.loadCachedSession(sessionId); } if (session != null) { session.setListener(listener); } } @Override public void start() { //NOOP } @Override public void stop() { //NOOP } /* * (non-Javadoc) * * @see org.jdiameter.common.api.data.ISessionDatasource#isClustered() */ @Override public boolean isClustered() { return true; } /* * (non-Javadoc) * * @see org.jdiameter.common.api.data.ISessionDatasource#getDataFactory(java. lang.Class) */ @Override public IAppSessionDataFactory getDataFactory(Class x) { return this.appSessionDataFactories.get(x); } @SuppressWarnings("unchecked") private SessionEntry loadCachedSession(String sessionId) { try { String className = getFieldValue(sessionId, AppSessionDataReplicatedImpl.SIFACE); if (className != null) { Class appSessionInterfaceClass = (Class) Thread.currentThread().getContextClassLoader().loadClass(className); // get factory; IAppSessionFactory fct = ((ISessionFactory) this.container.getSessionFactory()).getAppSessionFactory(appSessionInterfaceClass); if (fct == null) { logger.warn("Session with id:{}, is in replicated data source, but no Application Session Factory for:{}.", sessionId, appSessionInterfaceClass); } else { //Get the local cache to refresh BaseSession session = fct.getSession(sessionId, appSessionInterfaceClass); SessionEntry sessionEntry = new SessionEntry(session, (NetworkReqListener) session); sessions.put(sessionId, sessionEntry); return sessionEntry; } } else { logger.warn("Session with id:{}, is in replicated data source, but no session interface.", sessionId); } } catch (IllegalDiameterStateException | ClassNotFoundException e) { if (logger.isErrorEnabled()) { logger.error("Failed to obtain factory from stack..."); } } return null; } @Override public IContainer getContainer() { return this.container; } @SuppressWarnings("unchecked") private Map getFieldValues(String sessionId) { logger.debug("{}: Loading field values", sessionId); try { Map values; String jsonValues = dataSessions.get(sessionId); if (jsonValues == null) { values = new HashMap<>(); } else { values = mapper.readValue(jsonValues, Map.class); } logger.debug("{}: Loaded field values: {}", sessionId, values); return values; } catch (JsonProcessingException e) { throw new CachingException("Error setting field values", e); } }//getFieldValues private void setFieldValues(String sessionId, Map fieldValues) { logger.debug("{}: Saving the field values (to map): {}", sessionId, fieldValues); try { final String valueStr = mapper.writeValueAsString(fieldValues); dataSessions.put(sessionId, valueStr, -1, TimeUnit.SECONDS, 1, TimeUnit.DAYS); logger.debug("{}: Saving the field values (to cache): {}", sessionId, valueStr); } catch (JsonProcessingException e) { throw new CachingException("Error setting field values", e); } }//setFieldValues @Override @SuppressWarnings("unchecked") public T getFieldValue(String sessionId, String fieldName) { return (T) getFieldValues(sessionId).get(fieldName); }//getFieldValue @Override public void setFieldValue(String sessionId, String fieldName, Object value) { logger.trace("{}: Setting field {} = {}", sessionId, fieldName, value); Map values = getFieldValues(sessionId); values.put(fieldName, value); setFieldValues(sessionId, values); }//setFieldValue } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/acc/ServerAccSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.server.acc; import org.jdiameter.api.acc.ServerAccSession; import org.jdiameter.common.api.app.acc.ServerAccSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.acc.IServerAccSessionData; import java.io.Serializable; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ServerAccSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IServerAccSessionData { private static final String STATELESS = "STATELESS"; private static final String STATE = "STATE"; private static final String TS_TIMEOUT = "TS_TIMEOUT"; private static final String TS_TIMERID = "TS_TIMERID"; public ServerAccSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerAccSession.class); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#isStateless() */ @Override public boolean isStateless() { return toPrimitive(getFieldValue(STATELESS), true); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setStateless( boolean) */ @Override public void setStateless(boolean stateless) { setFieldValue(STATELESS, stateless); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# getServerCCASessionState() */ @Override public ServerAccSessionState getServerAccSessionState() { return ServerAccSessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# setServerCCASessionState * (org.jdiameter.common.api.app.cca.ServerCCASessionState) */ @Override public void setServerAccSessionState(ServerAccSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } @Override public void setTsTimeout(long value) { setFieldValue(TS_TIMEOUT, value); } @Override public long getTsTimeout() { return toPrimitive((Long) getFieldValue(TS_TIMEOUT)); } @Override public void setTsTimerId(Serializable value) { setFieldValue(TS_TIMERID, value); } @Override public Serializable getTsTimerId() { return getFieldValue(TS_TIMERID); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/auth/ServerAuthSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.server.auth; import org.jdiameter.api.auth.ServerAuthSession; import org.jdiameter.common.api.app.auth.ServerAuthSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.auth.IServerAuthSessionData; import java.io.Serializable; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ServerAuthSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IServerAuthSessionData { private static final String STATELESS = "STATELESS"; private static final String STATE = "STATE"; private static final String TS_TIMEOUT = "TS_TIMEOUT"; private static final String TS_TIMERID = "TS_TIMERID"; public ServerAuthSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerAuthSession.class); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#isStateless() */ @Override public boolean isStateless() { return toPrimitive(getFieldValue(STATELESS), true); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setStateless( boolean) */ @Override public void setStateless(boolean stateless) { setFieldValue(STATELESS, stateless); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# getServerCCASessionState() */ @Override public ServerAuthSessionState getServerAuthSessionState() { return ServerAuthSessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# setServerCCASessionState * (org.jdiameter.common.api.app.cca.ServerCCASessionState) */ @Override public void setServerAuthSessionState(ServerAuthSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } @Override public void setTsTimeout(long value) { setFieldValue(TS_TIMEOUT, value); } @Override public long getTsTimeout() { return toPrimitive((Long) getFieldValue(TS_TIMEOUT)); } @Override public void setTsTimerId(Serializable value) { setFieldValue(TS_TIMERID, value); } @Override public Serializable getTsTimerId() { return getFieldValue(TS_TIMERID); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/cca/ServerCCASessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.server.cca; import org.jdiameter.api.cca.ServerCCASession; import org.jdiameter.common.api.app.cca.ServerCCASessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.cca.IServerCCASessionData; import java.io.Serializable; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ServerCCASessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IServerCCASessionData { private static final String TCCID = "TXTIMER_ID"; private static final String STATELESS = "STATELESS"; private static final String STATE = "STATE"; public ServerCCASessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerCCASession.class); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#isStateless() */ @Override public boolean isStateless() { return toPrimitive(getFieldValue(STATELESS), true); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setStateless( boolean) */ @Override public void setStateless(boolean stateless) { setFieldValue(STATELESS, stateless); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# getServerCCASessionState() */ @Override public ServerCCASessionState getServerCCASessionState() { String state = getFieldValue(STATE, "IDLE"); return ServerCCASessionState.valueOf(state); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# setServerCCASessionState * (org.jdiameter.common.api.app.cca.ServerCCASessionState) */ @Override public void setServerCCASessionState(ServerCCASessionState state) { if (!state.name().equals(getFieldValue(STATE))) { setFieldValue(STATE, state.name()); } } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setTccTimerId (java.io.Serializable) */ @Override public void setTccTimerId(Serializable tccTimerId) { setFieldValue(TCCID, tccTimerId); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#getTccTimerId() */ @Override public Serializable getTccTimerId() { return getFieldValue(TCCID); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/cxdx/ServerCxDxSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.server.cxdx; import org.jdiameter.api.cxdx.ServerCxDxSession; import org.jdiameter.impl.ha.common.cxdx.CxDxSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.cxdx.IServerCxDxSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ServerCxDxSessionDataReplicatedImpl extends CxDxSessionDataReplicatedImpl implements IServerCxDxSessionData { public ServerCxDxSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerCxDxSession.class); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/gx/ServerGxSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.server.gx; import org.jdiameter.api.gx.ServerGxSession; import org.jdiameter.common.api.app.gx.ServerGxSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.gx.IServerGxSessionData; import java.io.Serializable; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ServerGxSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IServerGxSessionData { private static final String TCCID = "TCCID"; private static final String STATELESS = "STATELESS"; private static final String STATE = "STATE"; public ServerGxSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerGxSession.class); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#isStateless() */ @Override public boolean isStateless() { return toPrimitive(getFieldValue(STATELESS), true); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setStateless( boolean) */ @Override public void setStateless(boolean stateless) { setFieldValue(STATELESS, stateless); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# getServerCCASessionState() */ @Override public ServerGxSessionState getServerGxSessionState() { return ServerGxSessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# setServerCCASessionState * (org.jdiameter.common.api.app.cca.ServerCCASessionState) */ @Override public void setServerGxSessionState(ServerGxSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setTccTimerId (java.io.Serializable) */ @Override public void setTccTimerId(Serializable tccTimerId) { setFieldValue(TCCID, tccTimerId); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#getTccTimerId() */ @Override public Serializable getTccTimerId() { return getFieldValue(TCCID); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/rf/ServerRfSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.server.rf; import org.jdiameter.api.rf.ServerRfSession; import org.jdiameter.common.api.app.rf.ServerRfSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.rf.IServerRfSessionData; import java.io.Serializable; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ServerRfSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IServerRfSessionData { private static final String TS_TIMERID = "TCCID"; private static final String STATELESS = "STATELESS"; private static final String STATE = "STATE"; private static final String TS_TIMEOUT = "TS_TIMEOUT"; public ServerRfSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerRfSession.class); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#isStateless() */ @Override public boolean isStateless() { return toPrimitive(getFieldValue(STATELESS), true); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setStateless( boolean) */ @Override public void setStateless(boolean stateless) { setFieldValue(STATELESS, stateless); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# getServerCCASessionState() */ @Override public ServerRfSessionState getServerRfSessionState() { return ServerRfSessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# setServerCCASessionState * (org.jdiameter.common.api.app.cca.ServerCCASessionState) */ @Override public void setServerRfSessionState(ServerRfSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setTccTimerId (java.io.Serializable) */ @Override public void setTsTimerId(Serializable tccTimerId) { setFieldValue(TS_TIMERID, tccTimerId); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#getTccTimerId() */ @Override public Serializable getTsTimerId() { return getFieldValue(TS_TIMERID); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.rf.IServerRfSessionData#getTsTimeout() */ @Override public long getTsTimeout() { return toPrimitive((Long) getFieldValue(TS_TIMEOUT)); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.rf.IServerRfSessionData#setTsTimeout(long) */ @Override public void setTsTimeout(long l) { setFieldValue(TS_TIMEOUT, l); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/ro/ServerRoSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.server.ro; import org.jdiameter.api.ro.ServerRoSession; import org.jdiameter.common.api.app.ro.ServerRoSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.ro.IServerRoSessionData; import java.io.Serializable; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ServerRoSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IServerRoSessionData { private static final String TCCID = "TXTIMER_ID"; private static final String STATELESS = "STATELESS"; private static final String STATE = "STATE"; public ServerRoSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerRoSession.class); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#isStateless() */ @Override public boolean isStateless() { return toPrimitive(getFieldValue(STATELESS), true); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setStateless( boolean) */ @Override public void setStateless(boolean stateless) { setFieldValue(STATELESS, stateless); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# getServerCCASessionState() */ @Override public ServerRoSessionState getServerRoSessionState() { return ServerRoSessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# setServerCCASessionState * (org.jdiameter.common.api.app.cca.ServerCCASessionState) */ @Override public void setServerRoSessionState(ServerRoSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setTccTimerId (java.io.Serializable) */ @Override public void setTccTimerId(Serializable tccTimerId) { setFieldValue(TCCID, tccTimerId); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#getTccTimerId() */ @Override public Serializable getTccTimerId() { return getFieldValue(TCCID); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/rx/ServerRxSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.server.rx; import org.jdiameter.api.rx.ServerRxSession; import org.jdiameter.common.api.app.rx.ServerRxSessionState; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.rx.IServerRxSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ServerRxSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IServerRxSessionData { private static final String STATELESS = "STATELESS"; private static final String STATE = "STATE"; public ServerRxSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerRxSession.class); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#isStateless() */ @Override public boolean isStateless() { return toPrimitive(getFieldValue(STATELESS), true); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData#setStateless( boolean) */ @Override public void setStateless(boolean stateless) { setFieldValue(STATELESS, stateless); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# getServerCCASessionState() */ @Override public ServerRxSessionState getServerRxSessionState() { return ServerRxSessionState.valueOf(getFieldValue(STATE, "IDLE")); } /* * (non-Javadoc) * * @see org.jdiameter.server.impl.app.cca.IServerCCASessionData# setServerCCASessionState * (org.jdiameter.common.api.app.cca.ServerCCASessionState) */ @Override public void setServerRxSessionState(ServerRxSessionState state) { if (getFieldValue(STATE) == null) { setFieldValue(STATE, state.name()); } } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/s13/ServerS13SessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see */ package org.jdiameter.impl.ha.server.s13; import org.jdiameter.api.s13.ServerS13Session; import org.jdiameter.impl.ha.common.s13.S13SessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.s13.IServerS13SessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ServerS13SessionDataReplicatedImpl extends S13SessionDataReplicatedImpl implements IServerS13SessionData { public ServerS13SessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerS13Session.class); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/server/sh/ShServerSessionDataReplicatedImpl.java ================================================ /* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-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.jdiameter.impl.ha.server.sh; import org.jdiameter.api.sh.ServerShSession; import org.jdiameter.impl.ha.common.AppSessionDataReplicatedImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasource; import org.jdiameter.server.impl.app.sh.IShServerSessionData; /** * @author Bartosz Baranowski * @author Alexandre Mendonca */ public class ShServerSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements IShServerSessionData { public ShServerSessionDataReplicatedImpl(String sessionId, CachedSessionDatasource datasource) { super(sessionId, datasource); setAppSessionIface(ServerShSession.class); } } ================================================ FILE: core/jdiameter-ha/impl/src/main/java/org/jdiameter/impl/ha/timer/ReplicatedTimerFacilityImpl.java ================================================ package org.jdiameter.impl.ha.timer; import org.infinispan.client.hotrod.annotation.ClientListener; import org.jdiameter.api.BaseSession; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.impl.BaseSessionImpl; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.api.timer.ITimerFacility; import org.jdiameter.common.impl.app.AppSessionImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasourceImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; /** * Replicated implementation of {@link ITimerFacility} */ @ClientListener public class ReplicatedTimerFacilityImpl implements ITimerFacility { private static final Logger logger = LoggerFactory.getLogger(ReplicatedTimerFacilityImpl.class); public static final String TXTIMER_ID = "TXTIMER_ID"; private final CachedSessionDatasourceImpl sessionDataSource; private final Map timerMap = new ConcurrentHashMap<>(); private final Timer timer = new Timer(); public ReplicatedTimerFacilityImpl(IContainer container) { super(); ISessionDatasource datasource = container.getAssemblerFacility().getComponentInstance(ISessionDatasource.class); if (datasource instanceof CachedSessionDatasourceImpl cachedSessionDatasource) { this.sessionDataSource = cachedSessionDatasource; } else { throw new IllegalArgumentException("ReplicatedTimerFacilityImpl expects an ISessionDatasource of type 'CachedSessionDatasource' and is not compatible with " + datasource.getClass().getName()); } } /* * (non-Javadoc) * * @see org.jdiameter.common.api.timer.ITimerFacility#cancel(java.io.Serializable) */ @Override public void cancel(Serializable id) { String timerId = id.toString(); logger.debug("Cancelling timer with id {}", timerId); TimerTask task = timerMap.remove(timerId); if (task != null) { task.cancel(); }//if } /* * (non-Javadoc) * * @see org.jdiameter.common.api.timer.ITimerFacility#schedule(java.lang.String, java.lang.String, long) */ @Override public Serializable schedule(String sessionId, String timerName, long milliseconds) throws IllegalArgumentException { TimerTaskRunner runner = new TimerTaskRunner(sessionId, timerName, milliseconds); timerMap.put(runner.getTimerId(), runner); logger.debug("Scheduling {}ms timer for sessionId {} and timer id {}", milliseconds, sessionId, runner.getTimerId()); timer.schedule(runner, milliseconds); return runner.getTimerId(); } /** * TimerTaskRunner is a private internal class that extends TimerTask. * It is designed to handle the execution of scheduled timers associated with a session. * Each instance of TimerTaskRunner is uniquely identified by a generated UUID. */ private class TimerTaskRunner extends TimerTask { private final String sessionId; private final String timerName; private final long milliseconds; private final String timerId; public TimerTaskRunner(String sessionId, String timerName, long milliseconds) { this.sessionId = sessionId; this.timerName = timerName; this.milliseconds = milliseconds; this.timerId = sessionId + "-" + UUID.randomUUID(); } public String getTimerId() { return timerId; } @Override public void run() { if (timerMap.remove(timerId) != null) { String sessionTimerId = sessionDataSource.getFieldValue(sessionId, TXTIMER_ID); if (timerId.equals(sessionTimerId)) { BaseSession session = sessionDataSource.getSession(sessionId); if (session != null) { logger.debug("Scheduled timer for sessionId {} and timer id {} expired after {}ms", sessionId, timerId, milliseconds); try { if (!session.isAppSession()) { BaseSessionImpl impl = (BaseSessionImpl) session; impl.onTimer(timerName); } else { AppSessionImpl impl = (AppSessionImpl) session; impl.onTimer(timerName); } } catch (Exception e) { logger.error("Caught exception from session object!", e); } } } else { logger.debug("Timer with id {} is not associated with session {}", timerId, sessionId); } } else { logger.debug("Timer with id {} has been cancelled for session {}", timerId, sessionId); } } } } ================================================ FILE: core/jdiameter-ha/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter diameter-core-parent 2.5.1-SNAPSHOT ../pom.xml jdiameter-ha-parent pom Quarkus :: JDiameter Stack HA :: Parent api impl 2.21.2 com.fasterxml.jackson.core jackson-databind ${jackson.version} com.fasterxml.jackson.datatype jackson-datatype-jsr310 ${jackson.version} ================================================ FILE: core/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter quarkus-jdiameter-parent 2.5.1-SNAPSHOT ../pom.xml pom diameter-core-parent Quarkus :: JDiameter Core :: Parent jdiameter jdiameter-ha ================================================ FILE: docs/antora-playbook.yml ================================================ site: title: Offline Diameter Docs start_page: quarkus-jdiameter::index.adoc output: clean: true dir: target/site content: sources: - url: .. # common module containing just the main index branches: HEAD start_path: docs ui: bundle: url: https://github.com/eddiecarpenter/antora-ui-go-docs/releases/latest/download/ui-bundle.zip snapshot: true runtime: fetch: false cache_dir: ./cache asciidoc: attributes: kroki-fetch-diagram: true page-pagination: '' experimental: '' safe: 0 extensions: - asciidoctor-kroki ================================================ FILE: docs/antora.yml ================================================ name: quarkus-jdiameter title: JDiameter version: dev nav: - modules/ROOT/nav.adoc ================================================ FILE: docs/modules/ROOT/assets/images/.keepme ================================================ ================================================ FILE: docs/modules/ROOT/examples/.keepme ================================================ ================================================ FILE: docs/modules/ROOT/nav.adoc ================================================ * xref:index.adoc[Introduction] * xref:Diameter_User_Guide.adoc[Original JDiameter User Guide] * xref:Implementing-Diameter-Service.adoc[Implementing Diameter Service] ================================================ FILE: docs/modules/ROOT/pages/Author_Group.adoc ================================================ ================================================ FILE: docs/modules/ROOT/pages/Book_Info.adoc ================================================ ================================================ FILE: docs/modules/ROOT/pages/Chapter-Introduction.adoc ================================================ [[_introduction]] include::./includes/attributes.adoc[] = Introduction to {product-name} Diameter Diameter is a computer networking protocol for Authentication, Authorization and Accounting (), as defined in RFC3588. It is a successor to RADIUS, and has been designed to overcome certain RADIUS limitations: * No transport reliability and flexibility (Diameter uses TCP/SCTP instead of UDP). * No security within protocol (Diameter supports IPSec (mandatory) and TLS (optional)). * Limited address space for AVPs (Diameter uses 32-bit address space instead of 8-bit). * Only stateless mode is possible (Diameter supports both stateful and stateless modes). * Static peers (Diameter offers dynamic discovery, using DNS, SRV and NAPTR). * No peer alignment capabilities (Diameter introduces capabilities negotiation). * No support for transport layer failover. Diameter follows http://tools.ietf.org/html/rfc3539[RFC3539], which introduces correct procedures. * Limited support for roaming (Diameter introduces mechanisms for secure and scalable roaming). * No extension possible (Diameter allows extension - new commands and AVPs to be defined). Diameter offers all of the capabilities of the RADIUS protocol, and is compatible with RADIUS. It can also define extensions, or "Applications". Each application may introduce new types of messages, AVP codes, and state machines. The Message and AVP codes are assigned by the . Each application has its own Application ID and Vendor ID that is used to distinguish between applications. Application code is used to signal to other peers which operations are supported by the connecting peer (Capabilities Exchange / Negotiation). :leveloffset: +1 include::Section-Introduction-Message_Format.adoc[] :leveloffset: -1 [[_introduction_contents]] == Contents {product-name} core is built on top of three basic components: Stack:: Extensible Diameter Stack. It provides basic session support along with application specific sessions. Multiplexer (MUX):: Diameter Stack multiplexer. Allows different listeners to share the same stack instance. Dictionary:: Diameter Message and AVP Dictionary. Provides an API to access information about AVPs. Dictionary is embedded in the MUX. ================================================ FILE: docs/modules/ROOT/pages/Chapter-JDiameter.adoc ================================================ [[_jdiameter]] include::./includes/attributes.adoc[] = {product-name} Stack The Diameter Stack is the core component of the presented Diameter solution. It performs all necessary tasks to allow user interaction with the Diameter network. It manages the state of diameter peers and allows to route messages between them. For more details, refer to http://tools.ietf.org/html/rfc3588[RFC 3588]. The Diameter Stack currently supports the following application sessions: * Base * Credit Control Application (CCA) * Sh * Ro * Rf * Cx/Dx * Gx * Gq' * Rx :leveloffset: +1 include::Section-JDiameter-Design_Overview.adoc[] :leveloffset: -1 :leveloffset: +1 include::Section-JDiameter-Setup.adoc[] :leveloffset: -1 :leveloffset: +1 include::Section-JDiameter-Configuration.adoc[] :leveloffset: -1 :leveloffset: +1 include::Section-JDiameter-Source_Overview.adoc[] :leveloffset: -1 :leveloffset: +1 include::Section-JDiameter-Validator.adoc[] :leveloffset: -1 ================================================ FILE: docs/modules/ROOT/pages/Conventions.adoc ================================================ include::includes/attributes.adoc[] = Document Conventions This manual uses several conventions to highlight certain words and phrases and draw attention to specific pieces of information. In PDF and paper editions, this manual uses typefaces drawn from the https://fedorahosted.org/liberation-fonts/[Liberation Fonts] set. The Liberation Fonts set is also used in HTML editions if the set is installed on your system. If not, alternative but equivalent typefaces are displayed. Note: Red Hat Enterprise Linux 5 and later includes the Liberation Fonts set by default. == Typographic Conventions Four typographic conventions are used to call attention to specific words and phrases. These conventions, and the circumstances they apply to, are as follows. `Mono-spaced Bold` Used to highlight system input, including shell commands, file names and paths. Also used to highlight key caps and key-combinations. For example: [quote] To see the contents of the file [path]_my_next_bestselling_novel_ in your current working directory, enter the `cat my_next_bestselling_novel` command at the shell prompt and press kbd:[Enter] to execute the command. The above includes a file name, a shell command and a key cap, all presented in Mono-spaced Bold and all distinguishable thanks to context. Key-combinations can be distinguished from key caps by the hyphen connecting each part of a key-combination. For example: ____ Press kbd:[Enter] to execute the command. Press to switch to the first virtual terminal. Press to return to your X-Windows session. ____ The first sentence highlights the particular key cap to press. The second highlights two sets of three key caps, each set pressed simultaneously. If source code is discussed, class names, methods, functions, variable names and returned values mentioned within a paragraph will be presented as above, in `Mono-spaced Bold`. For example: [quote] File-related classes include [class]`filesystem` for file systems, [class]`file` for files, and [class]`dir` for directories. Each class has its own associated set of permissions. [app]`Proportional Bold` This denotes words or phrases encountered on a system, including application names; dialogue box text; labelled buttons; check-box and radio button labels; menu titles and sub-menu titles. For example: ____ Choose menu:System > Preferences > Mouse[] from the main menu bar to launch [app]`Mouse Preferences`. In the [label]#Buttons# tab, click the [label]#Left-handed mouse# check box and click btn:[Close] to switch the primary mouse button from the left to the right (making the mouse suitable for use in the left hand). To insert a special character into a [app]`gedit` file, choose menu:Applications > Accessories > Character Map[] from the main menu bar. Next, choose menu:Search > Find[] from the [app]`Character Map` menu bar, type the name of the character in the [label]#Search# field and click btn:[Next]. The character you sought will be highlighted in the [label]#Character Table#. Double-click this highlighted character to place it in the [label]#Text to copy# field and then click the btn:[Copy] button. Now switch back to your document and choose menu:Edit > Paste[] from the [app]`gedit` menu bar. ____ The above text includes application names; system-wide menu names and items; application-specific menu names; and buttons and text found within a GUI interface, all presented in Proportional Bold and all distinguishable by context. Note the menu:>[] shorthand used to indicate traversal through a menu and its sub-menus. This is to avoid the difficult-to-follow 'Select from the menu:Preferences[] sub-menu in the menu:System[] menu of the main menu bar' approach. `Mono-spaced Bold Italic` or [app]`Proportional Bold Italic` Whether Mono-spaced Bold or Proportional Bold, the addition of Italics indicates replaceable or variable text. Italics denotes text you do not input literally or displayed text that changes depending on circumstance. For example: ____ To connect to a remote machine using ssh, type `ssh username@domain.name` at a shell prompt. If the remote machine is [path]_example.com_ and your username on that machine is john, type `ssh john@example.com`. The `mount -o remount file-system` command remounts the named file system. For example, to remount the [path]_/home_ file system, the command is `mount -o remount /home`. To see the version of a currently installed package, use the `rpm -q package` command. It will return a result as follows: `package-version-release`. ____ Note the words in bold italics above —username, domain.name, file-system, package, version and release. Each word is a placeholder, either for text you enter when issuing a command or for text displayed by the system. Aside from standard usage for presenting the title of a work, italics denotes the first use of a new and important term. For example: [quote] When the Apache HTTP Server accepts requests, it dispatches child processes or threads to handle them. This group of child processes or threads is known as a [term]_server-pool_. Under Apache HTTP Server 2.0, the responsibility for creating and maintaining these server-pools has been abstracted to a group of modules called [term]_Multi-Processing Modules_ ([term]_MPMs_). Unlike other modules, only one module from the MPM group can be loaded by the Apache HTTP Server. == Pull-quote Conventions Two, commonly multi-line, data types are set off visually from the surrounding text. Output sent to a terminal is set in `Mono-spaced Roman` and presented thus: ---- books Desktop documentation drafts mss photos stuff svn books_tests Desktop1 downloads images notes scripts svgs ---- Source-code listings are also set in `Mono-spaced Roman` but are presented and highlighted as follows: [source,java] ---- package org.jboss.book.jca.ex1; import javax.naming.InitialContext; public class ExClient { public static void main(String args[]) throws Exception { InitialContext iniCtx = new InitialContext(); Object ref = iniCtx.lookup("EchoBean"); EchoHome home = (EchoHome) ref; Echo echo = home.create(); System.out.println("Created Echo"); System.out.println("Echo.echo('Hello') = " + echo.echo("Hello")); } } ---- == Notes and Warnings Finally, we use three visual styles to draw attention to information that might otherwise be overlooked. .Note [NOTE] ==== A note is a tip or shortcut or alternative approach to the task at hand. Ignoring a note should have no negative consequences, but you might miss out on a trick that makes your life easier. ==== .Important [IMPORTANT] ==== Important boxes detail things that are easily missed: configuration changes that only apply to the current session, or services that need restarting before an update will apply. Ignoring Important boxes won't cause data loss but may cause irritation and frustration. ==== .Warning [WARNING] ==== A Warning should not be ignored. Ignoring warnings will most likely cause data loss. ==== ================================================ FILE: docs/modules/ROOT/pages/Diameter_User_Guide.adoc ================================================ include::./includes/attributes.adoc[] = User Guide to {product-name} {project-version} :leveloffset: +1 include::Chapter-Introduction.adoc[] :leveloffset: -1 :leveloffset: +1 include::Chapter-JDiameter.adoc[] :leveloffset: -1 :leveloffset: +1 include::Revision_History.adoc[] :leveloffset: -1 ================================================ FILE: docs/modules/ROOT/pages/Implementing-Diameter-Service.adoc ================================================ include::includes/attributes.adoc[] = {product-name} The Diameter protocol is a computer networking protocol for Authentication, Authorisation and Accounting, as defined in link:https://datatracker.ietf.org/doc/html/rfc6733[RFC6733]. It is extensively used in the 3GPP telecommunication industry. JDiameter is an existing Java Diameter stack that supports the protocol. The original RestComm implementation (https://github.com/RestComm/jdiameter) is quite old, and its active support has stopped. The Quarkus Diameter extension has updated the JDiameter implementation for both a Quarkus JVM and a Native application. == Installation If you want to use this extension, you need to add the io.quarkiverse.jdiameter:quarkus-diameter extension first to your build file. For instance, with Maven, add the following dependency to your POM file: [source,xml] ---- 2.0.x io.quarkiverse.jdiameter quarkus-jdiameter ${quarkus.jdiameter.version} ---- == Implementing a Diameter Service To implement a Diameter service, a class must be defined and annotated with `@DiameterService` and optionally `@DiameterServiceOptions`. The `@DiameterServiceOption` annotation is used, among other things, to specify the Diameter configuration profile to use for the service. If it is not specified, the service will use the default configuration profile. The type of Diameter service is determined by the xref:_application_session_types[Diameter Application Session Listener] interfaces implemented by the service. The DiameterService interceptor will initialise all the configured services and start the Diameter stack (if it hasn't already started). === Example [source,java] ---- @DiameterService <1> @DiameterServiceOption("client1") <2> public class MyDiameterService implements ClientCCASessionListener <3> { @Override public void doCreditControlAnswer(ClientCCASession session, JCreditControlRequest request, JCreditControlAnswer answer) throws InternalException { //... } } ---- <1> Marking the class as a diameter service <2> The optional configuration option to apply to the diameter service. If not defined, the configuration will be used. <3> Implements the SessionListener associated with the `Session Type`. (See xref:_application_session_types[List] below) == Application Session Types The session listener determines the Diameter service session type it implements. The list below contains all the session types currently supported by the Diameter Service implementation. .Supported Application Session type. [options="header"] |=== | Session Type | Server Session Interface | Client Session Interface | Application | Reference | Acc | ServerAccSessionListener | ClientAccSessionListener | AccountingId[0:3] | link:https://datatracker.ietf.org/doc/html/rfc6733[RFC6733] | Auth | ServerAuthSessionListener | ClientAuthSessionListener | Internal | link:https://datatracker.ietf.org/doc/html/rfc6733[RFC6733] | CCA | ServerCCASessionListener | ClientCCASessionListener | AuthId[0:4] | link:https://datatracker.ietf.org/doc/html/rfc4006[RFC4006] | Gx | ServerGxSessionListener | ClientGxSessionListener | - | - | Rx | ClientRxSessionListener | ClientRxSessionListener | - | - | S6a | ServerS6aSessionListener | ClientS6aSessionListener | - | - | Gq | ServerGqSessionListener | ClientGqSessionListener | - | - | Sh | ServerShSessionListener | ClientShSessionListener | - | - | CxDx | ServerCxDxSessionListener | ClientCxDxSessionListener | AuthId[13019:16777216] AuthId[10415:16777216] | TS.29228 | S13 | ServerS13SessionListener | ClientS13SessionListener | - | - | Ro | ServerRoSessionListener | ClientRoSessionListener | AuthId[10415:4] | TS.32240 | Rf | ServerRfSessionListener | ClientRfSessionListener | AccountingId[10415:3] | TS.32240 |=== IMPORTANT: Only *one* implementation of a session listener per diameter stack is allowed per application. If the build phase detected that the same session listener is implemented more than once for the *same* diameter stack a `DiameterConfigException` exception will be generated. TIP: A Diameter service may implement more than one session listener. == Diameter Server mode If a Diameter service implements any of the ServerXXXSessionListeners, the Diameter Service interceptor automatically creates a network listener for that Diameter service. NOTE: The interceptor will skip creating a listener if it detects that the Diameter Service has implemented the `NetworkListener` interface. TIP: In most cases you do not need to implement your own `NetworkListener` and you can let the interceptor create one for you! == Injecting the Diameter stack An application can inject the diameter stack and configuration for a given configuration profile. NOTE: Only one stack is created per enabled configuration profile. TIP: The stack will only be active if there is a defined DiameterService for the stack. [source,java] ---- @ApplicationScoped public class Demo { @DiameterConfig <1> Stack stack; @DiameterConfig("test2") <2> Configuration test2Config; //... } ---- <1> Injecting the Diameter stack associated with the "" configuration. <2> Injecting the Diameter configuration for the "test2" configuration. == Using {product-name} in an high availability environment The {product-name} keeps track of each active session by storing the session information for each session. {product-name} also sets various timers linked to these sessions. In a standalone mode, the session state is stored locally, and the timers are defined in the local JVM. To use the diameter stack in a high availability (HA) mode, where two or more nodes are used in a load balance or failover mode, the sessions cannot be stored in local RAM. To use {product-name} in an HA environment the HA extensions must be loaded. The HA extensions store the session state in an Infinispan Cache and use Infinispan timers to implement the diameter timers. The HA extensions store the session information in a remote cache called `diameter`. TIP: The cache used can be changed by setting the `quarkus.diameter.parameter.caching-name` property The Quarkus extension automatically include the HA extensions. To use the HA components, the following configuration needs to be added: [source,properties] ---- quarkus.diameter.parameter.caching-name=drasessions <1> meter.extensions.session-datasource=org.jdiameter.impl.ha.data.CachedSessionDatasourceImpl quarkus.diameter.extensions.timer-facility=org.jdiameter.impl.ha.timer.ReplicatedTimerFacilityImpl ---- <1> This option changes the caching name from the default `diameter` to 'drasessions'. NOTE: The HA implementation depends on the Quarkus Infinispan client. You also need to provide the https://quarkus.io/guides/infinispan-client-reference#configuring-the-connection[Infinispan configuration] to make this all work. == Example Configuration The example configuration defines two sets of client diameter config. One is the default config, and the other is named config and is called 'test1'. [source,properties] ---- quarkus.diameter.local-peer.uri=aaa://ocsclient:1812 quarkus.diameter.local-peer.ip-addresses=0.0.0.0, 127.0.0.1 quarkus.diameter.local-peer.realm=server.test.com quarkus.diameter.local-peer.product-name=Diameter Test Client quarkus.diameter.local-peer.firmware-revision=1 quarkus.diameter.local-peer.applications.0.auth-appl-id=4 quarkus.diameter.local-peer.applications.1.auth-appl-id=4 quarkus.diameter.local-peer.applications.1.vendor-id=10415 quarkus.diameter.parameter.use-virtual-threads=true quarkus.diameter.network.peers.peer-uri=aaa://ocs.test.org:3868 quarkus.diameter.network.peers.ip=127.0.0.1 quarkus.diameter.network.peers.attempt-connect=true quarkus.diameter.network.peers.rating=0 quarkus.diameter.network.realms."server.test.com".peers=192.168.241.1,localhost quarkus.diameter.network.realms."server.test.com".local-action=local quarkus.diameter.network.realms."server.test.com".dynamic=false quarkus.diameter.network.realms."server.test.com".exp-time=1 quarkus.diameter.network.realms."server.test.com".application-id.auth-appl-id=4 quarkus.diameter.test1.local-peer.uri=aaa://ocsclient:1813 quarkus.diameter.test1.local-peer.ip-addresses[0]=0.0.0.0, 127.0.0.1 quarkus.diameter.test1.local-peer.realm=server.test.com quarkus.diameter.test1.local-peer.product-name=Diameter Test Client quarkus.diameter.test1.local-peer.firmware-revision=1 quarkus.diameter.test1.local-peer.applications.0.auth-appl-id=4 quarkus.diameter.test1.parameter.use-virtual-threads=true quarkus.diameter.test1.network.peers.peer-uri=aaa://ocs.test.org:3868 quarkus.diameter.test1.network.peers.ip=127.0.0.1 quarkus.diameter.test1.network.peers.attempt-connect=true quarkus.diameter.test1.network.peers.rating=0 quarkus.diameter.test1.network.realms."server.test.com".peers=192.168.241.1,localhost quarkus.diameter.test1.network.realms."server.test.com".local-action=local quarkus.diameter.test1.network.realms."server.test.com".dynamic=false quarkus.diameter.test1.network.realms."server.test.com".exp-time=1 quarkus.diameter.test1.network.realms."server.test.com".application-id.auth-appl-id=4 ---- TIP: For more information about the extension configuration, please refer to the <>. [[configuration-reference]] include::includes/quarkus-jdiameter.adoc[leveloffset=+1] ================================================ FILE: docs/modules/ROOT/pages/Java_Development_Kit-Installing_Configuring_and_Running.adoc ================================================ include::includes/attributes.adoc[] :sectnums!: [appendix] [[_jdk_installing_configuring_and_running]] = Java Development Kit (): Installing, Configuring and Running The [app]` Platform` is written in Java; therefore, before running any [app]`` server, you must have a working Java Runtime Environment () or Java Development Kit () installed on your system. In addition, the JRE or JDK you are using to run [app]`` must be version 5 or higherfootnote:[At this point in time, it is possible to run most servers, such as the JAIN SLEE, using a Java 6 JRE or JDK. Be aware, however, that presently the XML Document Management Server does not run on Java 6. We suggest checking the web site, forums or discussion pages if you need to inquire about the status of running the XML Document Management Server with Java 6.]. .Should I Install the JRE or JDK? Although you can run [app]`` servers using the Java Runtime Environment, we assume that most users are developers interested in developing Java-based, [app]``-driven solutions. Therefore, in this guide we take the tact of showing how to install the full Java Development Kit. .Should I Install the 32-Bit or the 64-Bit JDK, and Does It Matter? Briefly stated: if you are running on a 64-Bit Linux or Windows platform, you should consider installing and running the 64-bit JDK over the 32-bit one. Here are some heuristics for determining whether you would rather run the 64-bit Java Virtual Machine (JVM) over its 32-bit cousin for your application: * Wider datapath: the pipe between RAM and CPU is doubled, which improves the performance of memory-bound applications when using a 64-bit JVM. * 64-bit memory addressing gives virtually unlimited (1 exabyte) heap allocation. However large heaps affect garbage collection. * Applications that run with more than 1.5 GB of RAM (including free space for garbage collection optimization) should utilize the 64-bit JVM. * Applications that run on a 32-bit JVM and do not require more than minimal heap sizes will gain nothing from a 64-bit JVM. Barring memory issues, 64-bit hardware with the same relative clock speed and architecture is not likely to run Java applications faster than their 32-bit cousin. Note that the following instructions detail how to download and install the 32-bit JDK, although the steps are nearly identical for installing the 64-bit version. .Downloading You can download the Sun JDK 5.0 (Java 2 Development Kit) from Sun's website: http://java.sun.com/javase/downloads/index_jdk5.jsp. Click on the [label]#Download# link next to "JDK 5.0 Update [replaceable]``" (where [replaceable]`` is the latest minor version release number). On the next page, select your language and platform (both architecture--whether 32- or 64-bit--and operating system), read and agree to the `Java Development Kit 5.0 License Agreement`, and proceed to the download page. The Sun website will present two download alternatives to you: one is an RPM inside a self-extracting file (for example, [path]_jdk-1_5_0_16-linux-i586-rpm.bin_), and the other is merely a self-extracting file (e.g. [path]_jdk-1_5_0_16-linux-i586.bin_). If you are installing the JDK on Red Hat Enterprise Linux, Fedora, or another RPM-based Linux system, we suggest that you download the self-extracting file containing the RPM package, which will set up and use the SysV service scripts in addition to installing the JDK. We also suggest installing the self-extracting RPM file if you will be running [app]`` in a production environment. .Installing The following procedures detail how to install the Java Development Kit on both Linux and Windows. .Procedure: Installing the JDK on Linux . Regardless of which file you downloaded, you can install it on Linux by simply making sure the file is executable and then running it: + ---- ~]$ chmod +x "jdk-1_5_0_-linux--rpm.bin" ~]$ ./"jdk-1_5_0_-linux--rpm.bin" ---- .You Installed Using the Non-RPM Installer, but Want the SysV Service Scripts [NOTE] ==== If you download the non-RPM self-extracting file (and installed it), and you are running on an RPM-based system, you can still set up the SysV service scripts by downloading and installing one of the `-compat` packages from the JPackage project. Remember to download the `-compat` package which corresponds correctly to the minor release number of the JDK you installed. The compat packages are available from link:ftp://jpackage.hmdc.harvard.edu/JPackage/1.7/generic/RPMS.non-free/. ==== IMPORTANT: You do not need to install a `-compat` package in addition to the JDK if you installed the self-extracting RPM file! The `-compat` package merely performs the same SysV service script set up that the RPM version of the JDK installer does. .Procedure: Installing the JDK on Windows . Using Explorer, simply double-click the downloaded self-extracting installer and follow the instructions to install the JDK. .Configuring Configuring your system for the JDK consists in two tasks: setting the [var]`JAVA_HOME` environment variable, and ensuring that the system is using the proper JDK (or JRE) using the `alternatives` command. Setting [var]`JAVA_HOME` usually overrides the values for `java`, `javac` and `java_sdk_1.5.0` in `alternatives`, but we will set them all just to be safe and consistent. Setting the [var]`JAVA_HOME` Environment Variable on Generic Linux:: After installing the JDK, you must ensure that the [var]`JAVA_HOME` environment variable exists and points to the location of your JDK installation. Setting [var]`java`, [var]`javac` and [var]`java_sdk_1.5.0` Using the `alternatives` command :: _As the root user_, call `/usr/sbin/alternatives` with the [option]`--config java` option to select between JDKs and JREs installed on your system: Setting the [var]`JAVA_HOME` Environment Variable on Windows:: For information on how to set environment variables in Windows, refer to http://support.microsoft.com/kb/931715. .Testing Finally, to make sure that you are using the correct JDK or Java version (5 or higher), and that the java executable is in your [var]`PATH`, run the `java -version ` command in the terminal from your home directory: ---- ~]$ java -version java version "1.5.0_16" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b03) Java HotSpot(TM) Client VM (build 1.5.0_16-b03, mixed mode, sharing) ---- .Uninstalling There is usually no reason (other than space concerns) to remove a particular JDK from your system, given that you can switch between JDKs and JREs easily using `alternatives`, and/or by setting [var]`JAVA_HOME`. .Uninstalling the JDK on Linux On RPM-based systems, you can uninstall the JDK using the `yum remove ` command. .Uninstalling the JDK on Windows On Windows systems, check the JDK entry in the `Start` menu for an uninstall command, or use `Add/Remove Programs`. :sectnums: ================================================ FILE: docs/modules/ROOT/pages/Preface.adoc ================================================ include::includes/attributes.adoc[] :sectnums!: [preface] = Preface :leveloffset: 1 include::Section-Conventions.adoc[] :leveloffset: 0 :leveloffset: 1 include::Section-Feedback.adoc[] :leveloffset: 0 :sectnums: ================================================ FILE: docs/modules/ROOT/pages/Revision_History.adoc ================================================ :sectnums!: include::./includes/attributes.adoc[] [appendix] = Revision History :sectnums: ================================================ FILE: docs/modules/ROOT/pages/Section-Conventions.adoc ================================================ include::includes/attributes.adoc[] = Document Conventions This manual uses several conventions to highlight certain words and phrases and draw attention to specific pieces of information. In PDF and paper editions, this manual uses typefaces drawn from the https://fedorahosted.org/liberation-fonts/[Liberation Fonts] set. The Liberation Fonts set is also used in HTML editions if the set is installed on your system. If not, alternative but equivalent typefaces are displayed. Note: Red Hat Enterprise Linux 5 and later includes the Liberation Fonts set by default. == Typographic Conventions Four typographic conventions are used to call attention to specific words and phrases. These conventions, and the circumstances they apply to, are as follows. `Mono-spaced Bold` Used to highlight system input, including shell commands, file names and paths. Also used to highlight key caps and key-combinations. For example: [quote] To see the contents of the file [path]_my_next_bestselling_novel_ in your current working directory, enter the `cat my_next_bestselling_novel` command at the shell prompt and press kbd:[Enter] to execute the command. The above includes a file name, a shell command and a key cap, all presented in Mono-spaced Bold and all distinguishable thanks to context. Key-combinations can be distinguished from key caps by the hyphen connecting each part of a key-combination. For example: ____ Press kbd:[Enter] to execute the command. Press to switch to the first virtual terminal. Press to return to your X-Windows session. ____ The first sentence highlights the particular key cap to press. The second highlights two sets of three key caps, each set pressed simultaneously. If source code is discussed, class names, methods, functions, variable names and returned values mentioned within a paragraph will be presented as above, in `Mono-spaced Bold`. For example: [quote] File-related classes include [class]`filesystem` for file systems, [class]`file` for files, and [class]`dir` for directories. Each class has its own associated set of permissions. [app]`Proportional Bold` This denotes words or phrases encountered on a system, including application names; dialogue box text; labelled buttons; check-box and radio button labels; menu titles and sub-menu titles. For example: ____ Choose menu:System > Preferences > Mouse[] from the main menu bar to launch [app]`Mouse Preferences`. In the [label]#Buttons# tab, click the [label]#Left-handed mouse# check box and click btn:[Close] to switch the primary mouse button from the left to the right (making the mouse suitable for use in the left hand). To insert a special character into a [app]`gedit` file, choose menu:Applications > Accessories > Character Map[] from the main menu bar. Next, choose menu:Search > Find[] from the [app]`Character Map` menu bar, type the name of the character in the [label]#Search# field and click btn:[Next]. The character you sought will be highlighted in the [label]#Character Table#. Double-click this highlighted character to place it in the [label]#Text to copy# field and then click the btn:[Copy] button. Now switch back to your document and choose menu:Edit > Paste[] from the [app]`gedit` menu bar. ____ The above text includes application names; system-wide menu names and items; application-specific menu names; and buttons and text found within a GUI interface, all presented in Proportional Bold and all distinguishable by context. Note the menu:>[] shorthand used to indicate traversal through a menu and its sub-menus. This is to avoid the difficult-to-follow 'Select from the menu:Preferences[] sub-menu in the menu:System[] menu of the main menu bar' approach. `Mono-spaced Bold Italic` or [app]`Proportional Bold Italic` Whether Mono-spaced Bold or Proportional Bold, the addition of Italics indicates replaceable or variable text. Italics denotes text you do not input literally or displayed text that changes depending on circumstance. For example: ____ To connect to a remote machine using ssh, type `ssh username@domain.name` at a shell prompt. If the remote machine is [path]_example.com_ and your username on that machine is john, type `ssh john@example.com`. The `mount -o remount file-system` command remounts the named file system. For example, to remount the [path]_/home_ file system, the command is `mount -o remount /home`. To see the version of a currently installed package, use the `rpm -q package` command. It will return a result as follows: `package-version-release`. ____ Note the words in bold italics above —username, domain.name, file-system, package, version and release. Each word is a placeholder, either for text you enter when issuing a command or for text displayed by the system. Aside from standard usage for presenting the title of a work, italics denotes the first use of a new and important term. For example: [quote] When the Apache HTTP Server accepts requests, it dispatches child processes or threads to handle them. This group of child processes or threads is known as a [term]_server-pool_. Under Apache HTTP Server 2.0, the responsibility for creating and maintaining these server-pools has been abstracted to a group of modules called [term]_Multi-Processing Modules_ ([term]_MPMs_). Unlike other modules, only one module from the MPM group can be loaded by the Apache HTTP Server. == Pull-quote Conventions Two, commonly multi-line, data types are set off visually from the surrounding text. Output sent to a terminal is set in `Mono-spaced Roman` and presented thus: ---- books Desktop documentation drafts mss photos stuff svn books_tests Desktop1 downloads images notes scripts svgs ---- Source-code listings are also set in `Mono-spaced Roman` but are presented and highlighted as follows: [source,java] ---- package org.jboss.book.jca.ex1; import javax.naming.InitialContext; public class ExClient { public static void main(String args[]) throws Exception { InitialContext iniCtx = new InitialContext(); Object ref = iniCtx.lookup("EchoBean"); EchoHome home = (EchoHome) ref; Echo echo = home.create(); System.out.println("Created Echo"); System.out.println("Echo.echo('Hello') = " + echo.echo("Hello")); } } ---- == Notes and Warnings Finally, we use three visual styles to draw attention to information that might otherwise be overlooked. .Note [NOTE] ==== A note is a tip or shortcut or alternative approach to the task at hand. Ignoring a note should have no negative consequences, but you might miss out on a trick that makes your life easier. ==== .Important [IMPORTANT] ==== Important boxes detail things that are easily missed: configuration changes that only apply to the current session, or services that need restarting before an update will apply. Ignoring Important boxes won't cause data loss but may cause irritation and frustration. ==== .Warning [WARNING] ==== A Warning should not be ignored. Ignoring warnings will most likely cause data loss. ==== ================================================ FILE: docs/modules/ROOT/pages/Section-Feedback.adoc ================================================ include::includes/attributes.adoc[] = Provide feedback to the authors! (((feedback))) If you find a typographical error in this manual, or if you have thought of a way to make this manual better, we would love to hear from you! Please submit a report in the the {this-issue-tracker-url}, against the product '{product-name}`, or contact the authors. When submitting a bug report, be sure to mention the manual's identifier: {product-name} If you have a suggestion for improving the documentation, try to be as specific as possible when describing it. If you have found an error, please include the section number and some of the surrounding text so we can find it easily. ifdef::backend-docbook[] [index] == Index // Generated automatically by the DocBook toolchain. endif::backend-docbook[] ================================================ FILE: docs/modules/ROOT/pages/Section-Introduction-Message_Format.adoc ================================================ :leveloffset: +1 include::./includes/attributes.adoc[] :leveloffset: -1 [[_mf_message_format]] = Message Format Diameter is a byte based protocol. Each message has a fixed structure, which consists of two parts: header and payload. The message header structure is common for every message. The content is fixed, as is the length. Message header content includes the code, application and certain bit flags, which helps identify the message in Diameter scope. The message payload is built up of AVPs. Its content differs for each command and application, though they all define the Session-ID AVP as mandatory. .Diameter Message Structure image::dia-Introduction-dia-DiameterPacketFormat.png[] The header has the following fields: .Message Headers Version:: Indicates the Diameter protocol version. This value is always set to `1`. Message Length:: Indicates the Diameter message length, including the header fields. Flags:: Composed by eight bits, to provide information regarding the message. The first four bits in the flags octet have the following meaning: * R = The message is a request (1) or an answer (0). * P = The message is proxiable (1) and may be proxied, relayed or redirected, or it must be processed locally (0). * E = The message is an error message (1) or a regular message (0). * T = The message is potentially being re-transmitted (1) or being sent for the first time (0). The last four bits are reserved for future use, and should be set to 0. Command Code:: Indicates the command associated with the message. Application-ID:: Identifies the application to which the message is applicable for. The application is an authentication, accounting, or vendor specific application. The `application-id` in the header must be the same as what is contained in any relevant AVPs in the message. Hop-by-Hop ID:: A unique ID that is used to match requests and answers. The header field of the answer message must contain the same value present in the corresponding request. This is how answers are routed back to the peer that sent the message. End-to-End ID:: A time-limited unique ID that is used to to detect duplicate messages. The ID must be unique for at least four minutes. The answer message originator must ensure that this header contains the same value present in the corresponding request. The message payload is built up from AVPs. Each AVP has a similar structure: a header, and encoded data. Data can be simple (eg, integer, long) or complex (another encoded AVP). .Payload Structure image::dia-Introduction-dia-DiameterAVPLayout.png[] .Payload AVPs AVP Code:: Uniquely identifies the attribute, by combining the specified code with the value contained within the Vendor-ID header field. AVP numbers 1 to 255 are reserved for RADIUS backwards compatibility, and do not require the Vendor-ID header field. AVP numbers 256 and above are used exclusively for the Diameter protocol, and are allocated by IANA. Flags:: Bit flags that specify how each attribute must be handled. Flags octets have the following structure: V M P r r r r r. A full description is available in http://tools.ietf.org/html/rfc3588#section-4.1[Section 4.1 of RFC3588]. The first three bits have the following meaning: * V If set, indicates that optional octets (Vendor-ID) is present in AVP header. * M If set, it indicates that receiving peer must understand this AVP or send error answer. * P If set, it indicates the need for encryption for end-to-end security. The last 5 bits are reserved for future use, and should be set to 0. AVP Length:: Indicates the number of octets in the AVP, including the following information: * AVP Code * AVP Length * AVP Flags * Vendor-ID field (if present) * AVP Data Vendor-ID:: An optional octet that identifies the AVP in application space. AVP code and AVP Vendor-ID create a unique identifier for the AVP. ================================================ FILE: docs/modules/ROOT/pages/Section-JDiameter-Configuration.adoc ================================================ [[_jdiameter_configuration]] = Diameter Stack Configuration The stack is initially configured by parsing an XML file. The top level structure of the file is described below. Further explanation of each child element, and the applicable attributes, is provided later in this section. [source,xml] ---- ---- [source,xml] ---- ---- The element contains parameters that affect the local Diameter peer. The available elements and attributes are listed for reference. . Elements and Attributes :: Specifies the URI for the local peer. The URI has the following format: "aaa://FQDN:port". :: Contains one or more child element, which contain a single, valid IP address for the local peer, stored in the [parameter]`value` attribute of the IPAddress. :: Specifies the realm of the local peer, using the [parameter]`value` attribute. :: Specifies a numeric identifier that corresponds to the vendor ID allocated by IANA. :: Specifies the name of the local peer product. :: Specifies the version of the firmware. :: Optional parent element containing child elements that specify settings relating to the Overload Monitor. :: Supports child elements that specify the ID of the tracked application(s). It also supports the following properties: index Defines the index of this overload monitor, so priorities/orders can be specified. lowThreshold The low threshold for activation of the overload monitor. highThreshold The high threshold for activation of the overload monitor. :: Parent element containing child elements that specify information about the application. The child elements create a unique application identifier. The child elements are: Specifies the vendor ID for application definition. It supports a single property: "value". The Authentication Application ID for application definition. It supports a single property: "value". The Account Application ID for application definition. It supports a single property: "value". :: Contains a child element , which defines the list of default supported applications. It is used for the server side, when the stack is configured to accept incoming calls and there is an empty list of preconfigured peers (server is configured to accept any connection). [source,xml] ---- ---- The element contains elements that specify parameters for the Diameter stack. The available elements and attributes are listed for reference. If not specified otherwise, each tag supports a single property - "value", which indicates the value of the tag. . Elements and Attributes :: Specifies whether the stack will accept connections from undefined peers. The default value is `false`. :: Specifies whether duplicate message protection is enabled. The default value is `false`. :: Specifies the time each duplicate message is valid for (in extreme cases, it can live up to 2 * DuplicateTimer - 1 milliseconds). The default, minimum value is `240000` (4 minutes in milliseconds). :: Specifies the number of requests stored for duplicate protection. The default value is `5000`. :: Determines whether the URI should be used as FQDN. If it is set to `true`, the stack expects the destination/origin host to be in the format of "aaa://isdn.domain.com:3868" rather than the normal "isdn.domain.com". The default value is `false`. :: Determines how many tasks the peer state machine can have before rejecting the next task. This queue contains FSM events and messaging. :: Determines the timeout for messages other than protocol FSM messages. The delay is in milliseconds. :: Determines how long the stack waits for all resources to stop. The delays are in milliseconds. :: Determines how long it takes for CER/CEA exchanges to timeout if there is no response. The delays are in milliseconds. :: Determines how long the stack waits to retry the communication with a peer that has stopped answering DWR messages. The delay is in milliseconds. :: Determines how long it takes for a DWR/DWA exchange to timeout if there is no response. The delay is in milliseconds. :: Determines how long it takes for a DPR/DPA exchange to timeout if there is no response. The delay is in milliseconds. :: Determines how long it takes for the reconnection procedure to timeout. The delay is in milliseconds. :: Determines the number of threads for handling events in the Peer FSM. :: Controls the thread pool sizes for different aspects of the stack. It supports multiple [parameter]`Entity` child elements. [parameter]`Entity` elements configure thread groups. These elements support the following properties: name Specifies the name of the entity. size Specifies the thread pool size of the entity. The default supported entities are: ThreadGroup Determines the maximum thread count in other entities. ProcessingMessageTimer Determines the thread count for message processing tasks. DuplicationMessageTimer Specifies the thread pool for identifying duplicate messages. RedirectMessageTimer Specifies the thread pool for redirecting messages that do not need any further processing. PeerOverloadTimer Determines the thread pool for managing the overload monitor. ConnectionTimer Determines the thread pool for managing tasks regarding peer connection FSM. StatisticTimer Determines the thread pool for statistic gathering tasks. ApplicationSession Determines the thread pool for managing the invocation of application session FSMs, which will invoke listeners. [source,xml] ---- ---- The element contains elements that specify parameters for external peers. The available elements and attributes are listed for reference. . Elements and Attributes :: Parent element containing the child element , which specifies external peers and the way they connect. specifies the name of external peers, whether they should be treated as a server or client, and what rating the peer has externally. supports the following properties: name Specifies the name of the peer in the form of a URI. The structure is "aaa://[fqdn|ip]:port" (for example, "aaa://192.168.1.1:3868"). attempt_connect Determines if the stack should try to connect to this peer. This property accepts boolean values. rating Specifies the rating of this peer in order to achieve peer priorities/sorting. :: Parent element containing the child element , which specifies all realms that connect into the Diameter network. contains attributes and elements that describe different realms configured for the Core. It supports child elements, which define the applications supported. supports the following parameters: peers Comma separated list of peers. Each peer is represented by an IP Address or FQDN. local_action Determines the action the Local Peer will play on the specified realm: Act as a LOCAL peer. dynamic Specifies if this realm is dynamic. That is, peers that connect to peers with this realm name will be added to the realm peer list if not present already. exp_time The time before a peer belonging to this realm is removed if no connection is available. Below is an example configuration file for a server supporting the CCA, Sh and Ro Applications: [source,xml] ---- ---- [[_jdiameter_cluster_configuration]] == Cluster configuration The following list defines the requirements for enabling stack cluster mode * Add the following entries to the `Parameters` section of [path]_jdiameter-config.xml_: + [source,xml] ---- org.jdiameter.impl. ha.data.ReplicatedData org.jdiameter.impl.ha. timer.ReplicatedTimerFacilityImpl ---- * A proper `JBoss Cache` configuration file: [path]_jdiameter-jbc.xml_ (located in the [path]_config_ directory). + The following content is sufficient for the JBoss Cache configuration file: + [source,xml] ---- ---- ================================================ FILE: docs/modules/ROOT/pages/Section-JDiameter-Design_Overview.adoc ================================================ [[_jdiameter_design]] include::./includes/attributes.adoc[] = Diameter Stack Design [[_jdiameter_design_extensibility]] == Diameter Stack Extensibility Diameter Stack has been designed to be extensible. In order to achieve that, two set of APIs are defined by the stack - one that defines basic contracts between the user application and the stack, and one that defines contracts allowing the instance to inject custom objects into the stack to perform certain tasks (for example, [class]`SessionFactory`). [class]`ISessionFactory` declares additional methods that allow the developer to declare custom behaviour (for example, custom application sessions). Please refer to <<_jdiameter_source_overview_session_factory>> for more detailed information. .Diameter Stack Extensibility Visualization image::/DIA_2_x_JD_DESIGN.png[] The general pattern for interface declaration is: * The interface `ComponentInterface` declares the minimal set of methods for a component to perform its task. * The interface `IComponentInterface` provides additional behavior methods. Please refer to the java doc for a list of interfaces and descriptions of method contracts. [[_jdiameter_design_model]] == Diameter Stack Model Diameter Stack performs the following tasks: * Manages connections to remote peers. * Manages session objects. * Routes messages on behalf of sessions. * Receives and delivers messages to assigned listeners (usually a session object). Sessions use the stack and the services it provides to communicate with remote peers. The application is the only place that holds references to sessions. It can be seen as follows: .Diameter Application and Stack Model image::DIA_2_x_JD_stack_model.png[] [[_jdiameter_app_session_factories]] == Application Session Factories Application session factories perform two tasks: * server stack as factory for sessions. * server session objects as holders for session related resources, like state change listener, event listeners and context. The figure below shows the relationship between Application Session Factories and User Applications: .Application Session Factory and User Application image::DIA_2_x_JD_stack_appsession_1.png[] NOTE: Session context is a callback interface defined by some sessions. == Session Replication Diameter Stack supports replication of session data and state. Clustered stack instances can perform operations on session regardless of physical location. Imagine the logically clustered stack as follows: .Diameter Cluster image::DIA_2_x_JD_stack_cluster_1.png[] Stack only replicates non simple sessions. This is because simple sessions do not hold state and can be simply recreated by the application. Simple sessions include: * RawSessions * Sessions Diameter Cluster replicates the full state of sessions. However, it does not replicate resources that are entirely local to the stack instance, like session listeners. Local resource references are recreated once the session is being prepared to be used in the stack instance. Listeners (state and events) are fetched from the respective session factory instance. See <<_jdiameter_app_session_factories>> for more details. ================================================ FILE: docs/modules/ROOT/pages/Section-JDiameter-Setup.adoc ================================================ [[_jdiameter_setup]] include::./includes/attributes.adoc[] = {product-name} Stack Setup [[_jdiameter_preinstall_requirements_and_prerequisites]] == Pre-Install Requirements and Prerequisites Ensure that the following requirements have been met before continuing with the install. [[_jdiameter_hardware_requirements]] === Hardware Requirements {product-name} Stack does not have any hardware requirements. [[_jdiameter_software_prerequisites]] === Software Prerequisites {product-name} Stack has the following software dependencies: * slf4j [[_jdiameter_source_code]] == Source Code This section provides instructions on how to obtain and build the {product-name} Stack from source code. [[_jdiameter_release_source_building]] === Release Source Code Building . Downloading the source code + IMPORTANT: Subversion is used to manage its source code. Instructions for using Subversion, including install, can be found at http://svnbook.red-bean.com + Use SVN to checkout a specific release source, the base URL is {this-trunk-source-code-url} , then add the specific release version, lets consider &THIS.VERSION;. + [source] ---- [usr]$ git clone git@github.com:RestComm/jss7.git ---- . Building the source code + IMPORTANT: Maven 3.2.5 (or higher) is used to build the release. Instructions for using Maven2, including install, can be found at http://maven.apache.org + Use Maven to build the deployable unit binary. + [source] ---- [usr]$ cd - [usr]$ mvn install ---- + Once the process finishes you should have the files deployed in maven archive. [[_jdiameter_trunk_source_building]] === Development Trunk Source Building Follow the process in <<_jdiameter_release_source_building>>, replacing the SVN source code URL with {this-trunk-source-code-url} . ================================================ FILE: docs/modules/ROOT/pages/Section-JDiameter-Source_Overview.adoc ================================================ [[_jdiameter_source_overview]] include::./includes/attributes.adoc[] = Diameter Stack Source overview Diameter stack is built with the following basic components: Session Factory:: The Session Factory governs the creation of sessions - raw and specific application sessions. Raw and Application Sessions:: Sessions govern stateful message routing between peers. Specific application sessions consume different type of messages and act differently based on the data present. Stack:: The Stack governs all necessary components, which are used to establish connection and communicate with remote peers. NOTE: For more detailed information, please refer to the Javadoc or the simple examples that can be found here: https://github.com/RestComm/jdiameter/tree/master/testsuite/load[Git Testsuite HEAD]. [[_jdiameter_source_overview_session_factory]] == Session Factory [class]`SessionFactory` provides the stack user with access to session objects. It manages registered application session factories in order to allow for the creation of specific application sessions. A Session Factory instance can be obtained from the stack using the [method]`getSessionFactory()` method. The base [class]`SessionFactory` interface is defined below: [source,java] ---- package org.jdiameter.api; import org.jdiameter.api.app.AppSession; public interface SessionFactory { RawSession getNewRawSession() throws InternalException; Session getNewSession() throws InternalException; Session getNewSession(String sessionId) throws InternalException; T getNewAppSession(ApplicationId applicationId, Class userSession) throws InternalException; T getNewAppSession(String sessionId, ApplicationId applicationId, Class userSession) throws InternalException; } ---- However, since the stack is extensible, it is safe to cast the [class]`SessionFactory` object to this interface: [source,java] ---- package org.jdiameter.client.api; public interface ISessionFactory extends SessionFactory { T getNewAppSession(String sessionId, ApplicationId applicationId, java.lang.Class aClass, Object... args) throws InternalException; void registerAppFacory(Class sessionClass, IAppSessionFactory factory); void unRegisterAppFacory(Class sessionClass); IConcurrentFactory getConcurrentFactory(); } ---- [method]`RawSession getNewRawSession() throws InternalException;`:: This method creates a [class]`RawSession`. Raw sessions are meant as handles for code performing part of the routing decision on the stack's, such as rely agents for instance. [method]`Session getNewSession() throws InternalException;`:: This method creates a session that acts as the endpoint for peer communication (for a given session ID). It declares the method that works with the [class]`Request` and [class]`Answer` objects. A session created with this method has an autogenerated ID. It should be considered as a client session. [method]`Session getNewSession(String sessionId) throws InternalException;`:: As above. However, the created session has an ID equal to that passsed as an argument. This created session should be considered a server session. [method]` T getNewAppSession(ApplicationId applicationId, Class userSession) throws InternalException;`:: This method creates a new specific application session, identified by the application ID and class of the session passed. The session ID is generated by implementation. New application sessions should be considered as client sessions. It is safe to type cast the return value to class passed as an argument. This method delegates the call to a specific application session factory. [method]` T getNewAppSession(String sessionId, ApplicationId applicationId, Class userSession) throws InternalException;`:: As above. However, the session Id is equal to the argument passed. New sessions should be considered server sessions. [method]` T getNewAppSession(String sessionId, ApplicationId applicationId, java.lang.Class aClass, Object... args) throws InternalException;`:: As above. However, it allows the stack to pass some additional arguments. Passed values are implementation specifc. [method]`void registerAppFacory(Class sessionClass, IAppSessionFactory factory);`:: Registers the [parameter]`factory` for a certain [parameter]`sessionClass`. This factory will receive a delegated call when ever the [method]`getNewAppSession` method is called with an application class matching one from the register method. [method]`void unRegisterAppFacory(Class sessionClass);`:: Removes the application session factory registered for the [parameter]`sessionClass`. .SessionFactory use example ==== [source,java] ---- class Test implements EventListener { .... public void test(){ Stack stack = new StackImpl(); XMLConfiguration config = new XMLConfiguration(new FileInputStream(new File(configFile)); SessionFactory sessionFactory = stack.init(config); stack.start(); //perferctly legal, both factories are the same. sessionFactor = stack.getSessionFactory(); Session session = sessionFactory.getNewSession(); session.setRequestListener(this); Request r = session.createRequest(308,ApplicationId.createByAuth(100L,10101L), "mobicents.org","aaa://uas.fancyapp.mobicents.org"); //add avps specific for app session.send(r,this); } } ---- ==== .SessionFactory use example ==== [source,java] ---- class Test implements EventListener { Stack stack = new StackImpl(); XMLConfiguration config = new XMLConfiguration(new FileInputStream(new File(configFile)); ISessionFactory sessionFactory = (ISessionFactory)stack.init(config); stack.start(); //perferctly legal, both factories are the same. sessionFactor = (ISessionFactory)stack.getSessionFactory(); sessionFactory.registerAppFacory(ClientShSession.class, new ShClientSessionFactory(this)); //our implementation of factory does not require any parameters ClientShSession session = (ClientShSession) sessionFactory.getNewAppSession(null, null , ClientShSession.class, null); ... session.sendUserDataRequest(udr); } ---- ==== [[_jdiameter_source_overview_session]] == Sessions [class]`RawSessions`, [class]`Sessions` and [class]`ApplicationSessions` provide the means for dispatching and receiving messages. Specific implementation of [class]`ApplicationSession` may provide non standard methods. The [class]`RawSession` and the [class]`Session` life span is controlled entirely by the application. However, the [class]`ApplicationSession` life time depends on the implemented state machine. [class]`RawSession` is defined as follows: [source,java] ---- public interface BaseSession extends Wrapper, Serializable { long getCreationTime(); long getLastAccessedTime(); boolean isValid(); Future send(Message message) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; Future send(Message message, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void release(); } public interface RawSession extends BaseSession { Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp); Message createMessage(int commandCode, ApplicationId applicationId, long hopByHopIdentifier, long endToEndIdentifier, Avp... avp); Message createMessage(Message message, boolean copyAvps); void send(Message message, EventListener listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ---- [method]`long getCreationTime();`:: Returns the time stamp of this session creation. [method]`long getLastAccessedTime();`:: Returns the time stamp indicating the last sent or received operation. [method]`boolean isValid();`:: Returns `true` when this session is still valid (ie, [method]`release()` has not been called). [method]`void release();`:: Application calls this method to inform the user that the session should free any associated resource - it shall not be used anymore. [method]`Future send(Message message)`:: Sends a message in async mode. The [class]`Future` reference provides the means of accessing the answer once it is received [method]`void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit)`:: As above. Allows to specify the time out value for send operations. [method]`Message createMessage(int commandCode, ApplicationId applicationId, Avp... avp);`:: Creates a Diameter message. It should be explicitly set either as a request or answer. Passed parameters are used to build messages. [method]`Message createMessage(int commandCode, ApplicationId applicationId, long hopByHopIdentifier, long endToEndIdentifier, Avp... avp);`:: As above. However, it also allows for the Hop-by-Hop and End-to-End Identifiers in the message header to be set. This method should be used to create answers. [method]`Message createMessage(Message message, boolean copyAvps);`:: Clones a message and returns the created object. The copyAvps parameter defines whether basic AVPs (Session, Route and Proxy information) should be copied to the new object. [method]`void send(Message message, EventListener listener)`:: Sends a message. The answer will be delivered by the specified listener [method]`void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit)`:: As above. It also allows for the answer to be passed after timeout. [class]`Session` defines similar methods, with exactly the same purpose: [source,java] ---- public interface Session extends BaseSession { String getSessionId(); void setRequestListener(NetworkReqListener listener); Request createRequest(int commandCode, ApplicationId appId, String destRealm); Request createRequest(int commandCode, ApplicationId appId, String destRealm, String destHost); Request createRequest(Request prevRequest); void send(Message message, EventListener listener) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; void send(Message message, EventListener listener, long timeOut, TimeUnit timeUnit) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; } ---- == Application Session Factories In the table below, you can find session factories provided by current implementation, along with a short description: .Application Factories [cols="1,1,1,1",frame="all",options="header"] |=== | Factory class | Application type & id | Application | Reference | org.jdiameter.common.impl.app.acc.AccSessionFactoryImpl | AccountingId[0:3] | Acc | RFC3588 | org.jdiameter.common.impl.app.auth.AuthSessionFactoryImpl | Specific | Auth | RFC3588 | org.jdiameter.common.impl.app.cca.CCASessionFactoryImpl | AuthId[0:4] | CCA | RFC4006 | org.jdiameter.common.impl.app.sh.ShSessionFactoryImpl | AuthId[10415:16777217] | Sh | TS.29328, TS.29329 | org.jdiameter.common.impl.app.cxdx.CxDxSessionFactoryImpl | AuthId[13019:16777216] | Cx | TS.29228, TS.29229 | org.jdiameter.common.impl.app.cxdx.CxDxSessionFactoryImpl | AuthId[10415:16777216] | Dx | TS.29228, TS.29229 | org.jdiameter.common.impl.app.acc.AccSessionFactoryImpl | AccountingId[10415:3] | Rf | TS.32240 | org.jdiameter.common.impl.app.cca.CCASessionFactoryImpl | AuthId[10415:4] | Ro | TS.32240 |=== NOTE: There is no specific factory for Ro and Rf. Those applications reuse the respective session and session factories. NOTE: Application IDs contain two numbers - [VendorId:ApplicationId]. IMPORTANT: Spaces have been introduced in the `Factory class` column values to correctly render the table. Please remove them when using copy/paste. ================================================ FILE: docs/modules/ROOT/pages/Section-JDiameter-Validator-Configuration.adoc ================================================ [[_jdiameter_validator_configuration]] include::./includes/attributes.adoc[] = Validator Configuration The Validator is configured with a single XML file. This file contains the structure definition for both messages and AVPs. Upon creation of the Diameter Stack, the validator is initialized. It performs the initialization by looking up the [path]_dictionary.xml_ file in classpath. NOTE: The configuration file contains more data that `Validator` uses to build its data base. This is because the `Dictionary` uses the same file to configure itself. It reuses the AVP definitions, with some extra information like AVP type and flags. The configuration file has the following structure: [source,xml] ---- ---- :: The root element that contains the child elements comprising the validator and dictionary components. This element does not support any attributes. :: Specifies whether message validation is activated for sent and received stack messages. The element supports the following optional attributes: enabled Specifies whether the validator is activated or deactivated. If not specified, the validator is deactivated. sendLevel Determines the validation level for messages sent by the stack instance. Values determine if sent messages are not validated at all (OFF), only message level AVPs are checked (MESSAGE) or all AVPs are checked (ALL). receiveLevel Determines the validation level for messages received by the stack instance. Values determine if sent messages are not validated at all (OFF), only message level AVPs are checked (MESSAGE) or all AVPs are checked (ALL). :: Optional element that specifies the mapping between the vendor name, vendor ID, and vendor code. The element supports the following required attributes: name Specifies the vendor name. For example, "Hewlett Packard". vendor-id Specifies the unique ID associated with the vendor. For example, "HP". code Specifies the alpha-numeric code allocated to the vendor by IANA. For example, "11". The value must be unique for each declaration. . XML Attributes ==== [source,xml] ---- ... ---- ==== :: Defines the simple Attribute Value Pair (AVP) types. The element supports the following required attributes: type-name Specifies a type name in accordance with the acceptable base types defined in RFC 3588. For example; "Enumerated", "OctetString", "Integer32". type-parent Specifies the parent type name used to define the base characteristics of the type. The values are restricted to defined elements. For example; "OctetString", "UTF8String", "IPAddress". . XML Attributes ==== [source,xml] ---- ---- ==== :: Defines the specific applications used within the dictionary. Two child elements are supported by : and . The element supports the following attributes: id Specifies the unique ID allocated to the application. The attribute is used in all messages and forms part of the message header. name Optional attribute that specifies the logical name of the application. uri Optional attribute that specifies a link to additional application information. . XML Attributes ==== [source,xml] ---- ---- ==== :: Element containing information necessary to configure the Attribute Value Pairs. <<_table_avp_attributes>> contains the complete list of supported attributes, and their available values (if applicable). The element supports a number of child elements that are used to set finer parameters for the individual AVP. The supported elements are , , and . NOTE: Different sets of elements are supported by depending on its position in the dictionary.xml file. . Child Elements and Attributes ==== [source,xml] ---- ---- ==== :: Child element of that is used to match the AVP with the AVP type as defined in the element. The element supports the following mandatory attribute: type-name Specifies the type-name of the element. This is used to match the type-name value in the element. NOTE: is ignored if the element contains the element. :: Child element of that specifies the enumeration value for the specified AVP. is used only when the type-name attribute of is specified. The element supports the following mandatory attributes: name Specifies the name of a constant value that applies to the AVP. code Specifies the integer value associated with the name of the constant. The value is passed as a value of the AVP, and maps to the name attribute. NOTE: is ignored if the element contains the element. :: Child element of that specifies the AVP is a grouped type. A grouped AVP is one that has no element present. The element does not support any attributes, however the element is allowed as a child element. The , which specifies a reference to a grouped AVP, supports one mandatory attribute: name Specifies the name of the grouped AVP member. The value must match the defined AVP name. . Attributes [cols="1,1,1",frame="all",options="header"] |=== | Attribute Name (optional in brackets) | Explicit Values (default in brackets) | Description | name | | Specifies the name of the AVP. This is used to match the AVP definition to any grouped AVP references. For further information about grouped AVPs, refer to the element description in this section. | code | | Specifies the integer code of the AVP. | (vendor-id) | (none) | Used to match the vendor ID reference to the value defined in the element. | (multiplicity) | | Specifies the number of acceptable AVPs in a message using an explicit value. | | 0 | An AVP must not be present in the message. | | (0+) | Zero or more instances of the AVP must be present in the message. | | 0-1 | Zero, or one instance of the AVP may be present in the message. An error occurs if the message contains more than one instance of the AVP. | | 1 | One instance of the AVP must be present in the message. | | 1+ | At least one instance of the AVP must be present in the message. | may-encrypt | Yes \| (No) | Specifies whether the AVP can be encrypted. | protected | may \| must \| mustnot | Determines actual state of AVP that is expected, if it MUST be encrypted , may or MUST NOT. | vendor-bit | must \| mustnot | Specifies whether the Vendor ID should be set. | mandatory | may \| must \| mustnot | Determines if support for this AVP is mandatory in order to consume/process message. | vendor | | Specifies the defined vendor code, which is used by the child element |=== . XML Attributes ==== [source,xml] ---- ---- ==== :: Specifies the command for the application. The element supports the element, which specifies the structure of the command. The element supports the following attributes: name Optional parameter that specifies the message name for descriptive purposes. code Mandatory parameter that specifies the integer code of the message. request Mandatory parameter that specifies whether the declared command is a request or answer. The available values are "true" (request) or "false" (answer). NOTE: If the element is specified in , it does not support any child elements. The element only refers to defined AVPs when used in this context. . Elements and Attributes ==== [source,xml] ---- ---- ==== ================================================ FILE: docs/modules/ROOT/pages/Section-JDiameter-Validator-Source_Overview.adoc ================================================ [[_jdiameter_validator_source_overview]] include::./includes/attributes.adoc[] = Validator Source Overview The Validator API defines methods to access its database of AVPs and check if the AVP and message have the proper structure. The Validator is currently message oriented. This means that it declares methods that center on message consistency checks. The class containing all validation logic is [class]`org.jdiameter.common.impl.validation.DiameterMessageValidator`. + It exposes the following methods: public boolean isOn();:: Simple method to determine if the `Validator` is enabled. public ValidatorLevel getSendLevel();:: Returns the validation level of outgoing messages. It can have one of the following values: `OFF`, `MESSAGE`, `ALL`. public ValidatorLevel getReceiveLevel():: Returns the validation level of incoming messages. It can have one of the following values: `OFF`, `MESSAGE`, `ALL`. public void validate(Message msg, boolean incoming) throws JAvpNotAllowedException:: Performs validation on a message. Based on the [parameter]`incoming` flag, the correct validation level is applied. If validation fails, an exception with details is thrown. public void validate(Message msg, ValidatorLevel validatorLevel) throws JAvpNotAllowedException:: Performs validation on messages with a specified level. It is a programatical way to allow different levels of validation from those configured. If validation fails, a [class]`JAvpNotAllowedException` with details is thrown. NOTE: The current implementation provides more methods, however those are out of scope for this documentation. A simple example of a Validator use case is shown below: .Validator Message Check Example ==== The example below is pseudo-code. [source,java] ---- ... boolean isRequest = true; boolean isIncoming = false; DiameterMessageValidator messageValidator = DiameterMessageValidator.getInstance(); Message message = createMessage(UserDataRequest.MESSAGE_CODE, isRequest, applicationId); //add AVPs ... //perform check try{ messageValidator.validate(message, isIncoming); } catch(JAvpNotAllowedException e) { System.err.println("Failed to validate ..., avp code: " + e.getAvpCode() + " avp vendor:" + e.getVendorId() + ", message:" + e.getMessage()); } ---- ==== ================================================ FILE: docs/modules/ROOT/pages/Section-JDiameter-Validator.adoc ================================================ [[_jdiameter_validator]] include::./includes/attributes.adoc[] = Diameter Stack Validator Validator is one of the Stack features. The primary purpose of the Validator is to detect malformed messages, such as an Answer message containing a Destination-Host Attribute Value Pair (AVP). The Validator is capable of validating multi-leveled, grouped AVPs, excluding the following content types: * URI, or Identifier types. * Enumerated types against defined values. The Validator is only capable of checking structural integrity, not the content of the message. The Validator performs the following checks: Index:: Checks that the AVPs are in the correct place. For example, `Session-Id` must always be encoded before any other AVP. Multiplicity:: Checks that the message AVPs occur the proper number of times. For example, the Session-ID should only be present once. The `Validator` is called by the stack implementation. It is invoked after the message is received, but before it is dispatched to a remote peer. NOTE: This means that if the peer does not exist in the local peer table, the validator is not called, as the stack fails before calling it. :leveloffset: +1 include::Section-JDiameter-Validator-Configuration.adoc[] :leveloffset: -1 :leveloffset: +1 include::Section-JDiameter-Validator-Source_Overview.adoc[] :leveloffset: -1 ================================================ FILE: docs/modules/ROOT/pages/Setting_the_JBOSS_HOME_Environment_Variable.adoc ================================================ include::includes/attributes.adoc[] :sectnums!: [appendix] [[_jboss_home_setup]] = Setting the JBOSS_HOME Environment Variable The [app]` Platform` ([app]``) is built on top of the [app]``. You do not need to set the [var]`JBOSS_HOME` environment variable to run any of the [app]` Platform` servers _unless_ [var]`JBOSS_HOME` is _already_ set. The best way to know for sure whether [var]`JBOSS_HOME` was set previously or not is to perform a simple check which may save you time and frustration. .Checking to See If JBOSS_HOME is Set on Unix At the command line, `echo` `$JBOSS_HOME` to see if it is currently defined in your environment: ---- ~]$ echo $JBOSS_HOME ---- The [app]` Platform` and most &THIS.PLATFORM; servers are built on top of the [app]`` ([app]``). When the [app]` Platform` or &THIS.PLATFORM; servers are built _from source_, then [var]`JBOSS_HOME` _must_ be set, because the &THIS.PLATFORM; files are installed into (or "`over top of`" if you prefer) a clean [app]`` installation, and the build process assumes that the location pointed to by the [var]`JBOSS_HOME` environment variable at the time of building is the [app]`` installation into which you want it to install the &THIS.PLATFORM; files. This guide does not detail building the [app]` Platform` or any &THIS.PLATFORM; servers from source. It is nevertheless useful to understand the role played by [app]`JBoss AS` and [var]`JBOSS_HOME` in the &THIS.PLATFORM; ecosystem. The immediately-following section considers whether you need to set [var]`JBOSS_HOME` at all and, if so, when. The subsequent sections detail how to set [var]`JBOSS_HOME` on Unix and Windows IMPORTANT: Even if you fall into the category below of _not needing_ to set [var]`JBOSS_HOME`, you may want to for various reasons anyway. Also, even if you are instructed that you do _not need_ to set [var]`JBOSS_HOME`, it is good practice nonetheless to check and make sure that [var]`JBOSS_HOME` actually _isn't_ set or defined on your system for some reason. This can save you both time and frustration. You _DO NOT NEED_ to set [var]`JBOSS_HOME` if... * ...you have installed the [app]` Platform` binary distribution. * ...you have installed a &THIS.PLATFORM;server binary distribution _which bundles [app]``._ You _MUST_ set [var]`JBOSS_HOME` if... * ...you are installing the [app]` Platform` or any of the &THIS.PLATFORM; servers _from source_. * ...you are installing the [app]` Platform` binary distribution, or one of the &THIS.PLATFORM; server binary distributions, which _do not_ bundle [app]``. Naturally, if you installed the [app]` Platform` or one of the &THIS.PLATFORM; server binary releases which _do not_ bundle [app]``, yet requires it to run, then you should install before setting [var]`JBOSS_HOME` or proceeding with anything else. .Setting the JBOSS_HOME Environment Variable on Unix The [var]`JBOSS_HOME` environment variable must point to the directory which contains all of the files for the [app]` Platform` or individual &THIS.PLATFORM; server that you installed. As another hint, this topmost directory contains a [path]_bin_ subdirectory. Setting [var]`JBOSS_HOME` in your personal [path]_~/.bashrc_ startup script carries the advantage of retaining effect over reboots. Each time you log in, the environment variable is sure to be set for you, as a user. On Unix, it is possible to set [var]`JBOSS_HOME` as a system-wide environment variable, by defining it in [path]_/etc/bashrc_, but this method is neither recommended nor detailed in these instructions. .Procedure: To Set JBOSS_HOME on Unix... . Open the [path]_~/.bashrc_ startup script, which is a hidden file in your home directory, in a text editor, and insert the following line on its own line while substituting for the actual install location on your system: + ---- export JBOSS_HOME="/home////" ---- . Save and close the [path]_.bashrc_ startup script. . You should `source` the [path]_.bashrc_ script to force your change to take effect, so that [var]`JBOSS_HOME` becomes set for the current sessionfootnote:[Note that any other terminals which were opened prior to your having altered .bashrc will need to source ~/.bashrc as well should they require access to JBOSS_HOME.]. + ---- ~]$ source ~/.bashrc ---- . Finally, ensure that [var]`JBOSS_HOME` is set in the current session, and actually points to the correct location: + NOTE: The command line usage below is based upon a binary installation of the [app]` Platform`. In this sample output, [var]`JBOSS_HOME` has been set correctly to the [replaceable]`topmost_directory` of the [app]`` installation. Note that if you are installing one of the standalone [app]`` servers (with [app]`JBoss AS` bundled!), then [var]`JBOSS_HOME` would point to the [replaceable]`topmost_directory` of your server installation. + ---- ~]$ echo $JBOSS_HOME /home/silas/// ---- .Setting the JBOSS_HOME Environment Variable on Windows The [var]`JBOSS_HOME` environment variable must point to the directory which contains all of the files for the &THIS.PLATFORM;Platform or individual &THIS.PLATFORM;server that you installed. As another hint, this topmost directory contains a [path]_bin_ subdirectory. For information on how to set environment variables in recent versions of Windows, refer to http://support.microsoft.com/kb/931715. :sectnums: ================================================ FILE: docs/modules/ROOT/pages/includes/attributes.adoc ================================================ :project-version: 2.5.0 :examples-dir: ./../examples/ :authors: Eddie Carpenter :copyright: Apache2 :product-name: Quarkus JDiameter :description: {product-name} documentation :favicon: favicon.svg :email: eddie.carpenter@icloud.com :jee-platform: JBoss Application Server :jee-version: 1.8 :this-issue-tracker-url: https://github.com/quarkisverse/quarkus-jdiameter/issues :this-trunk-source-code-url: https://github.com/quarkisverse/quarkus-jdiameter ================================================ FILE: docs/modules/ROOT/pages/includes/quarkus-jdiameter.adoc ================================================ [.configuration-legend] icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime [.configuration-reference.searchable, cols="80,.^10,.^10"] |=== h|[.header-title]##Configuration property## h|Type h|Default h|[[quarkus-jdiameter_section_quarkus-diameter-local-peer]] [.section-name.section-level0]##link:#quarkus-jdiameter_section_quarkus-diameter-local-peer[The localPeer element contains parameters that affect the local Diameter peer]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-local-peer-uri]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-uri[`+++quarkus.diameter.local-peer.uri+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.uri+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.uri+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.uri+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the URI for the local peer. The URI has the following format: "aaa://FQDN:port". ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_URI+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_URI+++` endif::add-copy-button-to-env-var[] -- |string |`+++aaa://localhost:1812+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-tls-configuration-name]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-tls-configuration-name[`+++quarkus.diameter.local-peer.tls-configuration-name+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.tls-configuration-name+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.tls-configuration-name+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.tls-configuration-name+++[] endif::add-copy-button-to-config-props[] [.description] -- The name of the TLS configuration to use. If not set and the default TLS configuration is configured (`quarkus.tls.++*++`) then that will be used. If a name is configured, it uses the configuration from `quarkus.tls..++*++` If a name is configured, but no TLS configuration is found with that name then an error will be thrown. If no TLS configuration is set, and `quarkus.tls.++*++` is not configured, then, no security will be used ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_TLS_CONFIGURATION_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_TLS_CONFIGURATION_NAME+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-local-peer-ip-addresses]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-ip-addresses[`+++quarkus.diameter.local-peer.ip-addresses+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.ip-addresses+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.ip-addresses+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.ip-addresses+++[] endif::add-copy-button-to-config-props[] [.description] -- Contains one or more valid IP address for the local peer.` ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_IP_ADDRESSES+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_IP_ADDRESSES+++` endif::add-copy-button-to-env-var[] -- |list of string |`+++127.0.0.1+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-realm]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-realm[`+++quarkus.diameter.local-peer.realm+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.realm+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.realm+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.realm+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the realm of the local peer. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_REALM+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_REALM+++` endif::add-copy-button-to-env-var[] -- |string |`+++io.quarkiverse.diameter+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-product-name]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-product-name[`+++quarkus.diameter.local-peer.product-name+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.product-name+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.product-name+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.product-name+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the name of the local peer product ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_PRODUCT_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_PRODUCT_NAME+++` endif::add-copy-button-to-env-var[] -- |string |`+++Go Diameter+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-firmware-revision]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-firmware-revision[`+++quarkus.diameter.local-peer.firmware-revision+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.firmware-revision+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.firmware-revision+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.firmware-revision+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the version of the firmware. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_FIRMWARE_REVISION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_FIRMWARE_REVISION+++` endif::add-copy-button-to-env-var[] -- |long |`+++3+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-vendor-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-vendor-id[`+++quarkus.diameter.local-peer.vendor-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.vendor-id+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies a numeric identifier that corresponds to the vendor ID allocated by IANA. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_VENDOR_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_VENDOR_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` h|[[quarkus-jdiameter_section_quarkus-diameter-local-peer-applications]] [.section-name.section-level1]##link:#quarkus-jdiameter_section_quarkus-diameter-local-peer-applications[Contains a list of default supported applications]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-local-peer-applications-vendor-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-applications-vendor-id[`+++quarkus.diameter.local-peer.applications.vendor-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications.vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter.local-peer.applications."applications".vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications."applications".vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications.vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications.vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications."applications".vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications."applications".vendor-id+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the vendor ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_VENDOR_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_VENDOR_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-applications-auth-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-applications-auth-appl-id[`+++quarkus.diameter.local-peer.applications.auth-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications.auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter.local-peer.applications."applications".auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications."applications".auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications.auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications.auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications."applications".auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications."applications".auth-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Authentication Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_AUTH_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_AUTH_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-applications-acct-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-applications-acct-appl-id[`+++quarkus.diameter.local-peer.applications.acct-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications.acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter.local-peer.applications."applications".acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications."applications".acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications.acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications.acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications."applications".acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications."applications".acct-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Account Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_ACCT_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_ACCT_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` h|[[quarkus-jdiameter_section_quarkus-diameter-local-peer-overload-monitors]] [.section-name.section-level1]##link:#quarkus-jdiameter_section_quarkus-diameter-local-peer-overload-monitors[Optional parent element containing child elements that specify settings]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-index]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-index[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".index+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".index+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".index+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".index+++[] endif::add-copy-button-to-config-props[] [.description] -- Defines the index of this overload monitor, so priorities/orders can be specified. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__INDEX+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__INDEX+++` endif::add-copy-button-to-env-var[] -- |int |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-low-threshold]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-low-threshold[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".low-threshold+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".low-threshold+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".low-threshold+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".low-threshold+++[] endif::add-copy-button-to-config-props[] [.description] -- The low threshold for activation of the overload monitor. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__LOW_THRESHOLD+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__LOW_THRESHOLD+++` endif::add-copy-button-to-env-var[] -- |double |`+++0d+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-high-threshold]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-high-threshold[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".high-threshold+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".high-threshold+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".high-threshold+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".high-threshold+++[] endif::add-copy-button-to-config-props[] [.description] -- The high threshold for activation of the overload monitor. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__HIGH_THRESHOLD+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__HIGH_THRESHOLD+++` endif::add-copy-button-to-env-var[] -- |double |`+++0d+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-vendor-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-vendor-id[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.vendor-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.vendor-id+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the vendor ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_VENDOR_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_VENDOR_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-auth-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-auth-appl-id[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.auth-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.auth-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Authentication Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_AUTH_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_AUTH_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-acct-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-acct-appl-id[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.acct-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.acct-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Account Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_ACCT_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_ACCT_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` h|[[quarkus-jdiameter_section_quarkus-diameter-parameter]] [.section-name.section-level0]##link:#quarkus-jdiameter_section_quarkus-diameter-parameter[The Parameters element contains elements that specify parameters for the Diameter stack]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-parameter-accept-undefined-peer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-accept-undefined-peer[`+++quarkus.diameter.parameter.accept-undefined-peer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.accept-undefined-peer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.accept-undefined-peer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.accept-undefined-peer+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies whether the stack will accept connections from undefined peers. The default value is `false` ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_ACCEPT_UNDEFINED_PEER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_ACCEPT_UNDEFINED_PEER+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-duplicate-protection]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-duplicate-protection[`+++quarkus.diameter.parameter.duplicate-protection+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.duplicate-protection+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.duplicate-protection+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.duplicate-protection+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies whether duplicate message protection is enabled. The default value is `false`. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_PROTECTION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_PROTECTION+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-use-uri-as-fqdn]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-use-uri-as-fqdn[`+++quarkus.diameter.parameter.use-uri-as-fqdn+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.use-uri-as-fqdn+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.use-uri-as-fqdn+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.use-uri-as-fqdn+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines whether the URI should be used as FQDN. If it is set to `true`, the stack expects the destination/origin host to be in the format of "aaa://isdn.domain.com:3868" rather than the normal "isdn.domain.com". The default value is `false`. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_USE_URI_AS_FQDN+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_USE_URI_AS_FQDN+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-use-virtual-threads]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-use-virtual-threads[`+++quarkus.diameter.parameter.use-virtual-threads+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.use-virtual-threads+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.use-virtual-threads+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.use-virtual-threads+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies whether the stack should use virtual threads The default value is `false` ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_USE_VIRTUAL_THREADS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_USE_VIRTUAL_THREADS+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-duplicate-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-duplicate-timer[`+++quarkus.diameter.parameter.duplicate-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.duplicate-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.duplicate-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.duplicate-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the time each duplicate message is valid for (in extreme cases, it can live up to 2 ++*++ DuplicateTimer - 1 milliseconds). The default, minimum value is `240000` (4 minutes in milliseconds). ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_TIMER+++` endif::add-copy-button-to-env-var[] -- |long |`+++240000+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-duplicate-size]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-duplicate-size[`+++quarkus.diameter.parameter.duplicate-size+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.duplicate-size+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.duplicate-size+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.duplicate-size+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the number of requests stored for duplicate protection. The default value is `5000`. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_SIZE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_SIZE+++` endif::add-copy-button-to-env-var[] -- |int |`+++5000+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-queue-size]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-queue-size[`+++quarkus.diameter.parameter.queue-size+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.queue-size+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.queue-size+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.queue-size+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how many tasks the peer state machine can have before rejecting the next task. This queue contains FSM events and messaging ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_QUEUE_SIZE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_QUEUE_SIZE+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-message-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-message-timeout[`+++quarkus.diameter.parameter.message-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.message-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.message-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.message-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the timeout for messages other than protocol FSM messages. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_MESSAGE_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_MESSAGE_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-stop-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-stop-timeout[`+++quarkus.diameter.parameter.stop-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.stop-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.stop-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.stop-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long the stack waits for all resources to stop. The delays are in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_STOP_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_STOP_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-cea-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-cea-timeout[`+++quarkus.diameter.parameter.cea-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.cea-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.cea-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.cea-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for CER/CEA exchanges to timeout if there is no response. The delays are in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CEA_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CEA_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-iac-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-iac-timeout[`+++quarkus.diameter.parameter.iac-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.iac-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.iac-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.iac-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long the stack waits to retry the communication with a peer that has stopped answering DWR messages. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_IAC_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_IAC_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-dwa-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-dwa-timeout[`+++quarkus.diameter.parameter.dwa-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.dwa-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.dwa-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.dwa-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for a DWR/DWA exchange to timeout if there is no response. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DWA_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DWA_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-dpa-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-dpa-timeout[`+++quarkus.diameter.parameter.dpa-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.dpa-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.dpa-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.dpa-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for a DPR/DPA exchange to timeout if there is no response. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DPA_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DPA_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-rec-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-rec-timeout[`+++quarkus.diameter.parameter.rec-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.rec-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.rec-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.rec-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for the reconnection procedure to timeout. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_REC_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_REC_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-session-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-session-timeout[`+++quarkus.diameter.parameter.session-Timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.session-Timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.session-Timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.session-Timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for the session to timeout The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_SESSION_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_SESSION_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-peer-fsm-thread-count]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-peer-fsm-thread-count[`+++quarkus.diameter.parameter.peer-fsm-thread-count+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.peer-fsm-thread-count+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.peer-fsm-thread-count+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.peer-fsm-thread-count+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the number of threads for handling events in the Peer FSM. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_PEER_FSM_THREAD_COUNT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_PEER_FSM_THREAD_COUNT+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-bind-delay]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-bind-delay[`+++quarkus.diameter.parameter.bind-delay+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.bind-delay+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.bind-delay+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.bind-delay+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines a delay before binding. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_BIND_DELAY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_BIND_DELAY+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-thread-group]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-thread-group[`+++quarkus.diameter.parameter.concurrent.thread-group+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.thread-group+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.thread-group+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.thread-group+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the maximum thread count in other entities. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_THREAD_GROUP+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_THREAD_GROUP+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-processing-message-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-processing-message-timer[`+++quarkus.diameter.parameter.concurrent.processing-message-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.processing-message-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.processing-message-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.processing-message-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread count for message processing tasks. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_PROCESSING_MESSAGE_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_PROCESSING_MESSAGE_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-duplication-message-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-duplication-message-timer[`+++quarkus.diameter.parameter.concurrent.duplication-message-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.duplication-message-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.duplication-message-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.duplication-message-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the thread pool for identifying duplicate messages. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_DUPLICATION_MESSAGE_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_DUPLICATION_MESSAGE_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-redirect-message-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-redirect-message-timer[`+++quarkus.diameter.parameter.concurrent.redirect-message-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.redirect-message-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.redirect-message-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.redirect-message-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the thread pool for redirecting messages that do not need any further processing. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_REDIRECT_MESSAGE_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_REDIRECT_MESSAGE_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-peer-overload-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-peer-overload-timer[`+++quarkus.diameter.parameter.concurrent.peer-overload-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.peer-overload-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.peer-overload-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.peer-overload-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread pool for managing the overload monitor. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_PEER_OVERLOAD_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_PEER_OVERLOAD_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-connection-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-connection-timer[`+++quarkus.diameter.parameter.concurrent.connection-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.connection-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.connection-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.connection-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread pool for managing tasks regarding peer connection FSM. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_CONNECTION_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_CONNECTION_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-statistic-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-statistic-timer[`+++quarkus.diameter.parameter.concurrent.statistic-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.statistic-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.statistic-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.statistic-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread pool for statistic gathering tasks. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_STATISTIC_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_STATISTIC_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-application-session]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-application-session[`+++quarkus.diameter.parameter.concurrent.application-session+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.application-session+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.application-session+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.application-session+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread pool for managing the invocation of application session FSMs, which will invoke listeners. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_APPLICATION_SESSION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_APPLICATION_SESSION+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-caching-name]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-caching-name[`+++quarkus.diameter.parameter.caching-name+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.caching-name+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.caching-name+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.caching-name+++[] endif::add-copy-button-to-config-props[] [.description] -- The caching name to be used if HA datasource is used ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CACHING_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CACHING_NAME+++` endif::add-copy-button-to-env-var[] -- |string |`+++diameter+++` h|[[quarkus-jdiameter_section_quarkus-diameter-network]] [.section-name.section-level0]##link:#quarkus-jdiameter_section_quarkus-diameter-network[The Network< element contains elements that specify parameters for external peers]## h|Type h|Default h|[[quarkus-jdiameter_section_quarkus-diameter-network-peers]] [.section-name.section-level1]##link:#quarkus-jdiameter_section_quarkus-diameter-network-peers[List of external peers and the way they connect]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-peer-uri]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-peer-uri[`+++quarkus.diameter.network.peers."peers".peer-uri+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".peer-uri+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".peer-uri+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".peer-uri+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the name of the peer in the form of a URI. The structure is "aaa://++[++fqdn++\|++ip++]++:port" (for example, "aaa://192.168.1.1:3868"). ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__PEER_URI+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__PEER_URI+++` endif::add-copy-button-to-env-var[] -- |string |`+++aaa://localhost:3868+++` a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-rating]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-rating[`+++quarkus.diameter.network.peers."peers".rating+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".rating+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".rating+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".rating+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the rating of this peer in order to achieve peer priorities/sorting. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__RATING+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__RATING+++` endif::add-copy-button-to-env-var[] -- |int |`+++1+++` a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-ip]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-ip[`+++quarkus.diameter.network.peers."peers".ip+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".ip+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".ip+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".ip+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the actual ip for the peer-uri, for example 192.168.1.1 ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__IP+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__IP+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-port-range]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-port-range[`+++quarkus.diameter.network.peers."peers".port-range+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".port-range+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".port-range+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".port-range+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies a port range to accept connection override the port number in peer-uri ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__PORT_RANGE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__PORT_RANGE+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-attempt-connect]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-attempt-connect[`+++quarkus.diameter.network.peers."peers".attempt-connect+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".attempt-connect+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".attempt-connect+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".attempt-connect+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines if the stack should try to connect to this peer. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__ATTEMPT_CONNECT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__ATTEMPT_CONNECT+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-tls-configuration-name]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-tls-configuration-name[`+++quarkus.diameter.network.peers."peers".tls-configuration-name+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".tls-configuration-name+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".tls-configuration-name+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".tls-configuration-name+++[] endif::add-copy-button-to-config-props[] [.description] -- The name of the TLS configuration to use. If not set and the default TLS configuration is configured (`quarkus.tls.++*++`) then that will be used. If a name is configured, it uses the configuration from `quarkus.tls..++*++` If a name is configured, but no TLS configuration is found with that name then an error will be thrown. If no TLS configuration is set, and `quarkus.tls.++*++` is not configured, then, no security will be used ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__TLS_CONFIGURATION_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__TLS_CONFIGURATION_NAME+++` endif::add-copy-button-to-env-var[] -- |string | h|[[quarkus-jdiameter_section_quarkus-diameter-network-realms]] [.section-name.section-level1]##link:#quarkus-jdiameter_section_quarkus-diameter-network-realms[List of all realms that connect into the Diameter network]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-peers]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-peers[`+++quarkus.diameter.network.realms."realms".peers+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".peers+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".peers+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".peers+++[] endif::add-copy-button-to-config-props[] [.description] -- Comma separated list of peers. Each peer is represented by an IP Address or FQDN. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__PEERS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__PEERS+++` endif::add-copy-button-to-env-var[] -- |string |`+++localhost+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-local-action]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-local-action[`+++quarkus.diameter.network.realms."realms".local-action+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".local-action+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".local-action+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".local-action+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the action the Local Peer will play on the specified realm: Act as a LOCAL peer. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__LOCAL_ACTION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__LOCAL_ACTION+++` endif::add-copy-button-to-env-var[] -- a|`local`, `relay`, `proxy`, `redirect` |`+++local+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-dynamic]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-dynamic[`+++quarkus.diameter.network.realms."realms".dynamic+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".dynamic+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".dynamic+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".dynamic+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies if this realm is dynamic. That is, peers that connect to peers with this realm name will be added to the realm peer list if not present already. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__DYNAMIC+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__DYNAMIC+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-exp-time]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-exp-time[`+++quarkus.diameter.network.realms."realms".exp-time+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".exp-time+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".exp-time+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".exp-time+++[] endif::add-copy-button-to-config-props[] [.description] -- The time before a peer belonging to this realm is removed if no connection is available. The time is in seconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__EXP_TIME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__EXP_TIME+++` endif::add-copy-button-to-env-var[] -- |long |`+++1+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-vendor-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-vendor-id[`+++quarkus.diameter.network.realms."realms".application-id[i].vendor-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".application-id[i].vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".application-id.vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".application-id.vendor-id+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the vendor ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__VENDOR_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__VENDOR_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-auth-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-auth-appl-id[`+++quarkus.diameter.network.realms."realms".application-id[i].auth-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".application-id[i].auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".application-id.auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".application-id.auth-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Authentication Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__AUTH_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__AUTH_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-acct-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-acct-appl-id[`+++quarkus.diameter.network.realms."realms".application-id[i].acct-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".application-id[i].acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".application-id.acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".application-id.acct-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Account Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__ACCT_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__ACCT_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-agent-properties]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-agent-properties[`+++quarkus.diameter.network.realms."realms".agent."properties"+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".agent."properties"+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".agent."properties"+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".agent."properties"+++[] endif::add-copy-button-to-config-props[] [.description] -- Retrieves the properties of the agent configuration. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__AGENT__PROPERTIES_+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__AGENT__PROPERTIES_+++` endif::add-copy-button-to-env-var[] -- |Map | h|[[quarkus-jdiameter_section_quarkus-diameter-extensions]] [.section-name.section-level0]##link:#quarkus-jdiameter_section_quarkus-diameter-extensions[The extensions elements contains elements that override existing components in the Diameter stack]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-extensions-metadata]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-metadata[`+++quarkus.diameter.extensions.metadata+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.metadata+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.metadata+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.metadata+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_METADATA+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_METADATA+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-message-parser]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-message-parser[`+++quarkus.diameter.extensions.message-parser+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.message-parser+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.message-parser+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.message-parser+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_MESSAGE_PARSER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_MESSAGE_PARSER+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-element-parser]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-element-parser[`+++quarkus.diameter.extensions.element-parser+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.element-parser+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.element-parser+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.element-parser+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_ELEMENT_PARSER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_ELEMENT_PARSER+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-router-engine]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-router-engine[`+++quarkus.diameter.extensions.router-engine+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.router-engine+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.router-engine+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.router-engine+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_ROUTER_ENGINE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_ROUTER_ENGINE+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-peer-controller]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-peer-controller[`+++quarkus.diameter.extensions.peer-controller+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.peer-controller+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.peer-controller+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.peer-controller+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_PEER_CONTROLLER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_PEER_CONTROLLER+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-realm-controller]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-realm-controller[`+++quarkus.diameter.extensions.realm-controller+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.realm-controller+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.realm-controller+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.realm-controller+++[] endif::add-copy-button-to-config-props[] [.description] -- The Realm Controller extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_REALM_CONTROLLER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_REALM_CONTROLLER+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-session-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-session-factory[`+++quarkus.diameter.extensions.session-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.session-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.session-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.session-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Session Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_SESSION_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_SESSION_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-transport-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-transport-factory[`+++quarkus.diameter.extensions.transport-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.transport-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.transport-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.transport-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Transport Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_TRANSPORT_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_TRANSPORT_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-connection]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-connection[`+++quarkus.diameter.extensions.connection+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.connection+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.connection+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.connection+++[] endif::add-copy-button-to-config-props[] [.description] -- The Connection extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_CONNECTION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_CONNECTION+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-network-guard]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-network-guard[`+++quarkus.diameter.extensions.network-guard+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.network-guard+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.network-guard+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.network-guard+++[] endif::add-copy-button-to-config-props[] [.description] -- The Network Guard extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_NETWORK_GUARD+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_NETWORK_GUARD+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-peer-fsm-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-peer-fsm-factory[`+++quarkus.diameter.extensions.peer-fsm-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.peer-fsm-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.peer-fsm-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.peer-fsm-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Peer Fsm Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_PEER_FSM_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_PEER_FSM_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-statistic-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-statistic-factory[`+++quarkus.diameter.extensions.statistic-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.statistic-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.statistic-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.statistic-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Statistic Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_STATISTIC_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_STATISTIC_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-concurrent-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-concurrent-factory[`+++quarkus.diameter.extensions.concurrent-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.concurrent-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.concurrent-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.concurrent-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Concurrent Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_CONCURRENT_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_CONCURRENT_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-concurrent-entity-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-concurrent-entity-factory[`+++quarkus.diameter.extensions.concurrent-entity-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.concurrent-entity-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.concurrent-entity-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.concurrent-entity-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Concurrent Entity Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_CONCURRENT_ENTITY_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_CONCURRENT_ENTITY_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-statistic-processor]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-statistic-processor[`+++quarkus.diameter.extensions.statistic-processor+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.statistic-processor+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.statistic-processor+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.statistic-processor+++[] endif::add-copy-button-to-config-props[] [.description] -- The Statistic Processor extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_STATISTIC_PROCESSOR+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_STATISTIC_PROCESSOR+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-network]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-network[`+++quarkus.diameter.extensions.network+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.network+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.network+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.network+++[] endif::add-copy-button-to-config-props[] [.description] -- The Network extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_NETWORK+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_NETWORK+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-session-datasource]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-session-datasource[`+++quarkus.diameter.extensions.session-datasource+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.session-datasource+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.session-datasource+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.session-datasource+++[] endif::add-copy-button-to-config-props[] [.description] -- The Session Datasource extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_SESSION_DATASOURCE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_SESSION_DATASOURCE+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-timer-facility]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-timer-facility[`+++quarkus.diameter.extensions.timer-facility+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.timer-facility+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.timer-facility+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.timer-facility+++[] endif::add-copy-button-to-config-props[] [.description] -- The Timer Facility extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_TIMER_FACILITY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_TIMER_FACILITY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-agent-redirect]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-agent-redirect[`+++quarkus.diameter.extensions.agent-redirect+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.agent-redirect+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.agent-redirect+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.agent-redirect+++[] endif::add-copy-button-to-config-props[] [.description] -- The Agent Redirect extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_REDIRECT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_REDIRECT+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-agent-configuration]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-agent-configuration[`+++quarkus.diameter.extensions.agent-configuration+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.agent-configuration+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.agent-configuration+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.agent-configuration+++[] endif::add-copy-button-to-config-props[] [.description] -- The Agent Configuration extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_CONFIGURATION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_CONFIGURATION+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-agent-proxy]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-agent-proxy[`+++quarkus.diameter.extensions.agent-proxy+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.agent-proxy+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.agent-proxy+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.agent-proxy+++[] endif::add-copy-button-to-config-props[] [.description] -- The Agent Proxy extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_PROXY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_PROXY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-overload-manager]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-overload-manager[`+++quarkus.diameter.extensions.overload-manager+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.overload-manager+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.overload-manager+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.overload-manager+++[] endif::add-copy-button-to-config-props[] [.description] -- The Overload Manager extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_OVERLOAD_MANAGER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_OVERLOAD_MANAGER+++` endif::add-copy-button-to-env-var[] -- |string | |=== ================================================ FILE: docs/modules/ROOT/pages/includes/quarkus-jdiameter_quarkus.diameter.adoc ================================================ [.configuration-legend] icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime [.configuration-reference.searchable, cols="80,.^10,.^10"] |=== h|[.header-title]##Configuration property## h|Type h|Default h|[[quarkus-jdiameter_section_quarkus-diameter-local-peer]] [.section-name.section-level0]##link:#quarkus-jdiameter_section_quarkus-diameter-local-peer[The localPeer element contains parameters that affect the local Diameter peer]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-local-peer-uri]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-uri[`+++quarkus.diameter.local-peer.uri+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.uri+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.uri+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.uri+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the URI for the local peer. The URI has the following format: "aaa://FQDN:port". ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_URI+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_URI+++` endif::add-copy-button-to-env-var[] -- |string |`+++aaa://localhost:1812+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-tls-configuration-name]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-tls-configuration-name[`+++quarkus.diameter.local-peer.tls-configuration-name+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.tls-configuration-name+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.tls-configuration-name+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.tls-configuration-name+++[] endif::add-copy-button-to-config-props[] [.description] -- The name of the TLS configuration to use. If not set and the default TLS configuration is configured (`quarkus.tls.++*++`) then that will be used. If a name is configured, it uses the configuration from `quarkus.tls..++*++` If a name is configured, but no TLS configuration is found with that name then an error will be thrown. If no TLS configuration is set, and `quarkus.tls.++*++` is not configured, then, no security will be used ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_TLS_CONFIGURATION_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_TLS_CONFIGURATION_NAME+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-local-peer-ip-addresses]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-ip-addresses[`+++quarkus.diameter.local-peer.ip-addresses+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.ip-addresses+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.ip-addresses+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.ip-addresses+++[] endif::add-copy-button-to-config-props[] [.description] -- Contains one or more valid IP address for the local peer.` ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_IP_ADDRESSES+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_IP_ADDRESSES+++` endif::add-copy-button-to-env-var[] -- |list of string |`+++127.0.0.1+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-realm]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-realm[`+++quarkus.diameter.local-peer.realm+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.realm+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.realm+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.realm+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the realm of the local peer. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_REALM+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_REALM+++` endif::add-copy-button-to-env-var[] -- |string |`+++io.quarkiverse.diameter+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-product-name]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-product-name[`+++quarkus.diameter.local-peer.product-name+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.product-name+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.product-name+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.product-name+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the name of the local peer product ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_PRODUCT_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_PRODUCT_NAME+++` endif::add-copy-button-to-env-var[] -- |string |`+++Go Diameter+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-firmware-revision]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-firmware-revision[`+++quarkus.diameter.local-peer.firmware-revision+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.firmware-revision+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.firmware-revision+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.firmware-revision+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the version of the firmware. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_FIRMWARE_REVISION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_FIRMWARE_REVISION+++` endif::add-copy-button-to-env-var[] -- |long |`+++3+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-vendor-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-vendor-id[`+++quarkus.diameter.local-peer.vendor-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.vendor-id+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies a numeric identifier that corresponds to the vendor ID allocated by IANA. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_VENDOR_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_VENDOR_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` h|[[quarkus-jdiameter_section_quarkus-diameter-local-peer-applications]] [.section-name.section-level1]##link:#quarkus-jdiameter_section_quarkus-diameter-local-peer-applications[Contains a list of default supported applications]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-local-peer-applications-vendor-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-applications-vendor-id[`+++quarkus.diameter.local-peer.applications.vendor-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications.vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter.local-peer.applications."applications".vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications."applications".vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications.vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications.vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications."applications".vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications."applications".vendor-id+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the vendor ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_VENDOR_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_VENDOR_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-applications-auth-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-applications-auth-appl-id[`+++quarkus.diameter.local-peer.applications.auth-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications.auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter.local-peer.applications."applications".auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications."applications".auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications.auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications.auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications."applications".auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications."applications".auth-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Authentication Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_AUTH_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_AUTH_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-applications-acct-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-applications-acct-appl-id[`+++quarkus.diameter.local-peer.applications.acct-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications.acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter.local-peer.applications."applications".acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.applications."applications".acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications.acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications.acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.applications."applications".acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.applications."applications".acct-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Account Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_ACCT_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_APPLICATIONS_ACCT_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` h|[[quarkus-jdiameter_section_quarkus-diameter-local-peer-overload-monitors]] [.section-name.section-level1]##link:#quarkus-jdiameter_section_quarkus-diameter-local-peer-overload-monitors[Optional parent element containing child elements that specify settings]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-index]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-index[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".index+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".index+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".index+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".index+++[] endif::add-copy-button-to-config-props[] [.description] -- Defines the index of this overload monitor, so priorities/orders can be specified. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__INDEX+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__INDEX+++` endif::add-copy-button-to-env-var[] -- |int |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-low-threshold]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-low-threshold[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".low-threshold+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".low-threshold+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".low-threshold+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".low-threshold+++[] endif::add-copy-button-to-config-props[] [.description] -- The low threshold for activation of the overload monitor. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__LOW_THRESHOLD+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__LOW_THRESHOLD+++` endif::add-copy-button-to-env-var[] -- |double |`+++0d+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-high-threshold]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-high-threshold[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".high-threshold+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".high-threshold+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".high-threshold+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".high-threshold+++[] endif::add-copy-button-to-config-props[] [.description] -- The high threshold for activation of the overload monitor. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__HIGH_THRESHOLD+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__HIGH_THRESHOLD+++` endif::add-copy-button-to-env-var[] -- |double |`+++0d+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-vendor-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-vendor-id[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.vendor-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.vendor-id+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the vendor ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_VENDOR_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_VENDOR_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-auth-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-auth-appl-id[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.auth-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.auth-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Authentication Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_AUTH_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_AUTH_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-acct-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-local-peer-overload-monitors-overload-monitors-application-id-acct-appl-id[`+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.acct-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.local-peer.overload-monitors."overload-monitors".application-id.acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".local-peer.overload-monitors."overload-monitors".application-id.acct-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Account Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_ACCT_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_LOCAL_PEER_OVERLOAD_MONITORS__OVERLOAD_MONITORS__APPLICATION_ID_ACCT_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` h|[[quarkus-jdiameter_section_quarkus-diameter-parameter]] [.section-name.section-level0]##link:#quarkus-jdiameter_section_quarkus-diameter-parameter[The Parameters element contains elements that specify parameters for the Diameter stack]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-parameter-accept-undefined-peer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-accept-undefined-peer[`+++quarkus.diameter.parameter.accept-undefined-peer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.accept-undefined-peer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.accept-undefined-peer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.accept-undefined-peer+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies whether the stack will accept connections from undefined peers. The default value is `false` ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_ACCEPT_UNDEFINED_PEER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_ACCEPT_UNDEFINED_PEER+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-duplicate-protection]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-duplicate-protection[`+++quarkus.diameter.parameter.duplicate-protection+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.duplicate-protection+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.duplicate-protection+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.duplicate-protection+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies whether duplicate message protection is enabled. The default value is `false`. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_PROTECTION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_PROTECTION+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-use-uri-as-fqdn]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-use-uri-as-fqdn[`+++quarkus.diameter.parameter.use-uri-as-fqdn+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.use-uri-as-fqdn+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.use-uri-as-fqdn+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.use-uri-as-fqdn+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines whether the URI should be used as FQDN. If it is set to `true`, the stack expects the destination/origin host to be in the format of "aaa://isdn.domain.com:3868" rather than the normal "isdn.domain.com". The default value is `false`. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_USE_URI_AS_FQDN+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_USE_URI_AS_FQDN+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-use-virtual-threads]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-use-virtual-threads[`+++quarkus.diameter.parameter.use-virtual-threads+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.use-virtual-threads+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.use-virtual-threads+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.use-virtual-threads+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies whether the stack should use virtual threads The default value is `false` ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_USE_VIRTUAL_THREADS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_USE_VIRTUAL_THREADS+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-duplicate-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-duplicate-timer[`+++quarkus.diameter.parameter.duplicate-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.duplicate-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.duplicate-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.duplicate-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the time each duplicate message is valid for (in extreme cases, it can live up to 2 ++*++ DuplicateTimer - 1 milliseconds). The default, minimum value is `240000` (4 minutes in milliseconds). ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_TIMER+++` endif::add-copy-button-to-env-var[] -- |long |`+++240000+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-duplicate-size]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-duplicate-size[`+++quarkus.diameter.parameter.duplicate-size+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.duplicate-size+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.duplicate-size+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.duplicate-size+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the number of requests stored for duplicate protection. The default value is `5000`. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_SIZE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DUPLICATE_SIZE+++` endif::add-copy-button-to-env-var[] -- |int |`+++5000+++` a| [[quarkus-jdiameter_quarkus-diameter-parameter-queue-size]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-queue-size[`+++quarkus.diameter.parameter.queue-size+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.queue-size+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.queue-size+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.queue-size+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how many tasks the peer state machine can have before rejecting the next task. This queue contains FSM events and messaging ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_QUEUE_SIZE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_QUEUE_SIZE+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-message-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-message-timeout[`+++quarkus.diameter.parameter.message-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.message-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.message-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.message-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the timeout for messages other than protocol FSM messages. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_MESSAGE_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_MESSAGE_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-stop-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-stop-timeout[`+++quarkus.diameter.parameter.stop-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.stop-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.stop-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.stop-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long the stack waits for all resources to stop. The delays are in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_STOP_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_STOP_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-cea-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-cea-timeout[`+++quarkus.diameter.parameter.cea-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.cea-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.cea-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.cea-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for CER/CEA exchanges to timeout if there is no response. The delays are in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CEA_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CEA_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-iac-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-iac-timeout[`+++quarkus.diameter.parameter.iac-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.iac-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.iac-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.iac-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long the stack waits to retry the communication with a peer that has stopped answering DWR messages. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_IAC_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_IAC_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-dwa-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-dwa-timeout[`+++quarkus.diameter.parameter.dwa-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.dwa-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.dwa-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.dwa-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for a DWR/DWA exchange to timeout if there is no response. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DWA_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DWA_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-dpa-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-dpa-timeout[`+++quarkus.diameter.parameter.dpa-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.dpa-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.dpa-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.dpa-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for a DPR/DPA exchange to timeout if there is no response. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_DPA_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_DPA_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-rec-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-rec-timeout[`+++quarkus.diameter.parameter.rec-timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.rec-timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.rec-timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.rec-timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for the reconnection procedure to timeout. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_REC_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_REC_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-session-timeout]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-session-timeout[`+++quarkus.diameter.parameter.session-Timeout+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.session-Timeout+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.session-Timeout+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.session-Timeout+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines how long it takes for the session to timeout The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_SESSION_TIMEOUT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_SESSION_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-peer-fsm-thread-count]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-peer-fsm-thread-count[`+++quarkus.diameter.parameter.peer-fsm-thread-count+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.peer-fsm-thread-count+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.peer-fsm-thread-count+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.peer-fsm-thread-count+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the number of threads for handling events in the Peer FSM. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_PEER_FSM_THREAD_COUNT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_PEER_FSM_THREAD_COUNT+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-bind-delay]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-bind-delay[`+++quarkus.diameter.parameter.bind-delay+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.bind-delay+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.bind-delay+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.bind-delay+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines a delay before binding. The delay is in milliseconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_BIND_DELAY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_BIND_DELAY+++` endif::add-copy-button-to-env-var[] -- |long | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-thread-group]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-thread-group[`+++quarkus.diameter.parameter.concurrent.thread-group+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.thread-group+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.thread-group+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.thread-group+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the maximum thread count in other entities. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_THREAD_GROUP+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_THREAD_GROUP+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-processing-message-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-processing-message-timer[`+++quarkus.diameter.parameter.concurrent.processing-message-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.processing-message-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.processing-message-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.processing-message-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread count for message processing tasks. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_PROCESSING_MESSAGE_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_PROCESSING_MESSAGE_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-duplication-message-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-duplication-message-timer[`+++quarkus.diameter.parameter.concurrent.duplication-message-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.duplication-message-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.duplication-message-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.duplication-message-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the thread pool for identifying duplicate messages. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_DUPLICATION_MESSAGE_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_DUPLICATION_MESSAGE_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-redirect-message-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-redirect-message-timer[`+++quarkus.diameter.parameter.concurrent.redirect-message-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.redirect-message-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.redirect-message-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.redirect-message-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the thread pool for redirecting messages that do not need any further processing. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_REDIRECT_MESSAGE_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_REDIRECT_MESSAGE_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-peer-overload-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-peer-overload-timer[`+++quarkus.diameter.parameter.concurrent.peer-overload-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.peer-overload-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.peer-overload-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.peer-overload-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread pool for managing the overload monitor. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_PEER_OVERLOAD_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_PEER_OVERLOAD_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-connection-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-connection-timer[`+++quarkus.diameter.parameter.concurrent.connection-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.connection-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.connection-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.connection-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread pool for managing tasks regarding peer connection FSM. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_CONNECTION_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_CONNECTION_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-statistic-timer]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-statistic-timer[`+++quarkus.diameter.parameter.concurrent.statistic-timer+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.statistic-timer+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.statistic-timer+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.statistic-timer+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread pool for statistic gathering tasks. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_STATISTIC_TIMER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_STATISTIC_TIMER+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-concurrent-application-session]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-concurrent-application-session[`+++quarkus.diameter.parameter.concurrent.application-session+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.concurrent.application-session+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.concurrent.application-session+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.concurrent.application-session+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the thread pool for managing the invocation of application session FSMs, which will invoke listeners. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_APPLICATION_SESSION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CONCURRENT_APPLICATION_SESSION+++` endif::add-copy-button-to-env-var[] -- |int | a| [[quarkus-jdiameter_quarkus-diameter-parameter-caching-name]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-parameter-caching-name[`+++quarkus.diameter.parameter.caching-name+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.parameter.caching-name+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".parameter.caching-name+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".parameter.caching-name+++[] endif::add-copy-button-to-config-props[] [.description] -- The caching name to be used if HA datasource is used ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_PARAMETER_CACHING_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_PARAMETER_CACHING_NAME+++` endif::add-copy-button-to-env-var[] -- |string |`+++diameter+++` h|[[quarkus-jdiameter_section_quarkus-diameter-network]] [.section-name.section-level0]##link:#quarkus-jdiameter_section_quarkus-diameter-network[The Network< element contains elements that specify parameters for external peers]## h|Type h|Default h|[[quarkus-jdiameter_section_quarkus-diameter-network-peers]] [.section-name.section-level1]##link:#quarkus-jdiameter_section_quarkus-diameter-network-peers[List of external peers and the way they connect]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-peer-uri]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-peer-uri[`+++quarkus.diameter.network.peers."peers".peer-uri+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".peer-uri+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".peer-uri+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".peer-uri+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the name of the peer in the form of a URI. The structure is "aaa://++[++fqdn++\|++ip++]++:port" (for example, "aaa://192.168.1.1:3868"). ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__PEER_URI+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__PEER_URI+++` endif::add-copy-button-to-env-var[] -- |string |`+++aaa://localhost:3868+++` a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-rating]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-rating[`+++quarkus.diameter.network.peers."peers".rating+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".rating+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".rating+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".rating+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the rating of this peer in order to achieve peer priorities/sorting. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__RATING+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__RATING+++` endif::add-copy-button-to-env-var[] -- |int |`+++1+++` a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-ip]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-ip[`+++quarkus.diameter.network.peers."peers".ip+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".ip+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".ip+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".ip+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the actual ip for the peer-uri, for example 192.168.1.1 ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__IP+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__IP+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-port-range]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-port-range[`+++quarkus.diameter.network.peers."peers".port-range+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".port-range+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".port-range+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".port-range+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies a port range to accept connection override the port number in peer-uri ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__PORT_RANGE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__PORT_RANGE+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-attempt-connect]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-attempt-connect[`+++quarkus.diameter.network.peers."peers".attempt-connect+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".attempt-connect+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".attempt-connect+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".attempt-connect+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines if the stack should try to connect to this peer. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__ATTEMPT_CONNECT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__ATTEMPT_CONNECT+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-network-peers-peers-tls-configuration-name]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-peers-peers-tls-configuration-name[`+++quarkus.diameter.network.peers."peers".tls-configuration-name+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.peers."peers".tls-configuration-name+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.peers."peers".tls-configuration-name+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.peers."peers".tls-configuration-name+++[] endif::add-copy-button-to-config-props[] [.description] -- The name of the TLS configuration to use. If not set and the default TLS configuration is configured (`quarkus.tls.++*++`) then that will be used. If a name is configured, it uses the configuration from `quarkus.tls..++*++` If a name is configured, but no TLS configuration is found with that name then an error will be thrown. If no TLS configuration is set, and `quarkus.tls.++*++` is not configured, then, no security will be used ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__TLS_CONFIGURATION_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_PEERS__PEERS__TLS_CONFIGURATION_NAME+++` endif::add-copy-button-to-env-var[] -- |string | h|[[quarkus-jdiameter_section_quarkus-diameter-network-realms]] [.section-name.section-level1]##link:#quarkus-jdiameter_section_quarkus-diameter-network-realms[List of all realms that connect into the Diameter network]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-peers]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-peers[`+++quarkus.diameter.network.realms."realms".peers+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".peers+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".peers+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".peers+++[] endif::add-copy-button-to-config-props[] [.description] -- Comma separated list of peers. Each peer is represented by an IP Address or FQDN. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__PEERS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__PEERS+++` endif::add-copy-button-to-env-var[] -- |string |`+++localhost+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-local-action]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-local-action[`+++quarkus.diameter.network.realms."realms".local-action+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".local-action+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".local-action+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".local-action+++[] endif::add-copy-button-to-config-props[] [.description] -- Determines the action the Local Peer will play on the specified realm: Act as a LOCAL peer. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__LOCAL_ACTION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__LOCAL_ACTION+++` endif::add-copy-button-to-env-var[] -- a|`local`, `relay`, `proxy`, `redirect` |`+++local+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-dynamic]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-dynamic[`+++quarkus.diameter.network.realms."realms".dynamic+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".dynamic+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".dynamic+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".dynamic+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies if this realm is dynamic. That is, peers that connect to peers with this realm name will be added to the realm peer list if not present already. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__DYNAMIC+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__DYNAMIC+++` endif::add-copy-button-to-env-var[] -- |boolean |`+++false+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-exp-time]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-exp-time[`+++quarkus.diameter.network.realms."realms".exp-time+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".exp-time+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".exp-time+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".exp-time+++[] endif::add-copy-button-to-config-props[] [.description] -- The time before a peer belonging to this realm is removed if no connection is available. The time is in seconds. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__EXP_TIME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__EXP_TIME+++` endif::add-copy-button-to-env-var[] -- |long |`+++1+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-vendor-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-vendor-id[`+++quarkus.diameter.network.realms."realms".application-id[i].vendor-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".application-id[i].vendor-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".application-id.vendor-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".application-id.vendor-id+++[] endif::add-copy-button-to-config-props[] [.description] -- Specifies the vendor ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__VENDOR_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__VENDOR_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-auth-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-auth-appl-id[`+++quarkus.diameter.network.realms."realms".application-id[i].auth-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".application-id[i].auth-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".application-id.auth-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".application-id.auth-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Authentication Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__AUTH_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__AUTH_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-acct-appl-id]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-application-id-i-acct-appl-id[`+++quarkus.diameter.network.realms."realms".application-id[i].acct-appl-id+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".application-id[i].acct-appl-id+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".application-id.acct-appl-id+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".application-id.acct-appl-id+++[] endif::add-copy-button-to-config-props[] [.description] -- The Account Application ID for application definition. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__ACCT_APPL_ID+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__APPLICATION_ID_I__ACCT_APPL_ID+++` endif::add-copy-button-to-env-var[] -- |long |`+++0+++` a| [[quarkus-jdiameter_quarkus-diameter-network-realms-realms-agent-properties]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-network-realms-realms-agent-properties[`+++quarkus.diameter.network.realms."realms".agent."properties"+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.network.realms."realms".agent."properties"+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".network.realms."realms".agent."properties"+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".network.realms."realms".agent."properties"+++[] endif::add-copy-button-to-config-props[] [.description] -- Retrieves the properties of the agent configuration. ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__AGENT__PROPERTIES_+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_NETWORK_REALMS__REALMS__AGENT__PROPERTIES_+++` endif::add-copy-button-to-env-var[] -- |Map | h|[[quarkus-jdiameter_section_quarkus-diameter-extensions]] [.section-name.section-level0]##link:#quarkus-jdiameter_section_quarkus-diameter-extensions[The extensions elements contains elements that override existing components in the Diameter stack]## h|Type h|Default a| [[quarkus-jdiameter_quarkus-diameter-extensions-metadata]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-metadata[`+++quarkus.diameter.extensions.metadata+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.metadata+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.metadata+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.metadata+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_METADATA+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_METADATA+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-message-parser]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-message-parser[`+++quarkus.diameter.extensions.message-parser+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.message-parser+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.message-parser+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.message-parser+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_MESSAGE_PARSER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_MESSAGE_PARSER+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-element-parser]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-element-parser[`+++quarkus.diameter.extensions.element-parser+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.element-parser+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.element-parser+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.element-parser+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_ELEMENT_PARSER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_ELEMENT_PARSER+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-router-engine]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-router-engine[`+++quarkus.diameter.extensions.router-engine+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.router-engine+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.router-engine+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.router-engine+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_ROUTER_ENGINE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_ROUTER_ENGINE+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-peer-controller]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-peer-controller[`+++quarkus.diameter.extensions.peer-controller+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.peer-controller+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.peer-controller+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.peer-controller+++[] endif::add-copy-button-to-config-props[] [.description] -- The MetaData extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_PEER_CONTROLLER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_PEER_CONTROLLER+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-realm-controller]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-realm-controller[`+++quarkus.diameter.extensions.realm-controller+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.realm-controller+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.realm-controller+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.realm-controller+++[] endif::add-copy-button-to-config-props[] [.description] -- The Realm Controller extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_REALM_CONTROLLER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_REALM_CONTROLLER+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-session-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-session-factory[`+++quarkus.diameter.extensions.session-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.session-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.session-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.session-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Session Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_SESSION_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_SESSION_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-transport-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-transport-factory[`+++quarkus.diameter.extensions.transport-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.transport-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.transport-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.transport-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Transport Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_TRANSPORT_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_TRANSPORT_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-connection]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-connection[`+++quarkus.diameter.extensions.connection+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.connection+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.connection+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.connection+++[] endif::add-copy-button-to-config-props[] [.description] -- The Connection extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_CONNECTION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_CONNECTION+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-network-guard]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-network-guard[`+++quarkus.diameter.extensions.network-guard+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.network-guard+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.network-guard+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.network-guard+++[] endif::add-copy-button-to-config-props[] [.description] -- The Network Guard extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_NETWORK_GUARD+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_NETWORK_GUARD+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-peer-fsm-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-peer-fsm-factory[`+++quarkus.diameter.extensions.peer-fsm-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.peer-fsm-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.peer-fsm-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.peer-fsm-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Peer Fsm Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_PEER_FSM_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_PEER_FSM_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-statistic-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-statistic-factory[`+++quarkus.diameter.extensions.statistic-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.statistic-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.statistic-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.statistic-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Statistic Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_STATISTIC_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_STATISTIC_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-concurrent-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-concurrent-factory[`+++quarkus.diameter.extensions.concurrent-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.concurrent-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.concurrent-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.concurrent-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Concurrent Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_CONCURRENT_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_CONCURRENT_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-concurrent-entity-factory]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-concurrent-entity-factory[`+++quarkus.diameter.extensions.concurrent-entity-factory+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.concurrent-entity-factory+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.concurrent-entity-factory+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.concurrent-entity-factory+++[] endif::add-copy-button-to-config-props[] [.description] -- The Concurrent Entity Factory extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_CONCURRENT_ENTITY_FACTORY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_CONCURRENT_ENTITY_FACTORY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-statistic-processor]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-statistic-processor[`+++quarkus.diameter.extensions.statistic-processor+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.statistic-processor+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.statistic-processor+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.statistic-processor+++[] endif::add-copy-button-to-config-props[] [.description] -- The Statistic Processor extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_STATISTIC_PROCESSOR+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_STATISTIC_PROCESSOR+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-network]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-network[`+++quarkus.diameter.extensions.network+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.network+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.network+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.network+++[] endif::add-copy-button-to-config-props[] [.description] -- The Network extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_NETWORK+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_NETWORK+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-session-datasource]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-session-datasource[`+++quarkus.diameter.extensions.session-datasource+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.session-datasource+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.session-datasource+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.session-datasource+++[] endif::add-copy-button-to-config-props[] [.description] -- The Session Datasource extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_SESSION_DATASOURCE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_SESSION_DATASOURCE+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-timer-facility]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-timer-facility[`+++quarkus.diameter.extensions.timer-facility+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.timer-facility+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.timer-facility+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.timer-facility+++[] endif::add-copy-button-to-config-props[] [.description] -- The Timer Facility extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_TIMER_FACILITY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_TIMER_FACILITY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-agent-redirect]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-agent-redirect[`+++quarkus.diameter.extensions.agent-redirect+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.agent-redirect+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.agent-redirect+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.agent-redirect+++[] endif::add-copy-button-to-config-props[] [.description] -- The Agent Redirect extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_REDIRECT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_REDIRECT+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-agent-configuration]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-agent-configuration[`+++quarkus.diameter.extensions.agent-configuration+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.agent-configuration+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.agent-configuration+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.agent-configuration+++[] endif::add-copy-button-to-config-props[] [.description] -- The Agent Configuration extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_CONFIGURATION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_CONFIGURATION+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-agent-proxy]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-agent-proxy[`+++quarkus.diameter.extensions.agent-proxy+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.agent-proxy+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.agent-proxy+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.agent-proxy+++[] endif::add-copy-button-to-config-props[] [.description] -- The Agent Proxy extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_PROXY+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_AGENT_PROXY+++` endif::add-copy-button-to-env-var[] -- |string | a| [[quarkus-jdiameter_quarkus-diameter-extensions-overload-manager]] [.property-path]##link:#quarkus-jdiameter_quarkus-diameter-extensions-overload-manager[`+++quarkus.diameter.extensions.overload-manager+++`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter.extensions.overload-manager+++[] endif::add-copy-button-to-config-props[] `+++quarkus.diameter."named-config".extensions.overload-manager+++` ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.diameter."named-config".extensions.overload-manager+++[] endif::add-copy-button-to-config-props[] [.description] -- The Overload Manager extension ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_DIAMETER_EXTENSIONS_OVERLOAD_MANAGER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] Environment variable: `+++QUARKUS_DIAMETER_EXTENSIONS_OVERLOAD_MANAGER+++` endif::add-copy-button-to-env-var[] -- |string | |=== ================================================ FILE: docs/modules/ROOT/pages/index.adoc ================================================ include::./includes/attributes.adoc[] = {product-name} Stack == Introduction Welcome to the {product-name} documentation. The documentation will guide you on how to install, configure and use {product-name} stack. NOTE: The {product-name} is a fork from the Restcomm JDiameter project, and the original project can be found at https://github.com/Restcomm/jdiameter. The documentation provided here includes the original project documentation with a new section being added covering how to use the stack in Quarkus. == Prerequisite Knowledge The reader must have a working knowledge of the 3GPP Diameter protocol. == Disclaimer The {product-name} stack is provided `as is` and the authors do not guarantee to be with out any faults. If you get to a point where you need a specific feature not currently supported or the Quarkus extension is not working as expected, send me an email at {email}, or even better, get involved! ================================================ FILE: docs/package.json ================================================ { "name": "quarkus-jdiameter", "description": "Quarkus JDiameter Documentation", "homepage": "http://localhost:8080", "private": true, "scripts": { "build": "antora --extension @antora/lunr-extension antora-playbook.yml", "preview": "http-server target/site -c-1" }, "dependencies": { "@antora/lunr-extension": "^1.0.0-alpha.8", "antora": "~3.1.7", "asciidoctor": "^3.0.4", "asciidoctor-kroki": "^0.18.1" } } ================================================ FILE: docs/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter quarkus-jdiameter-parent 2.5.1-SNAPSHOT ../pom.xml quarkus-jdiameter-docs Quarkus :: JDiameter Docs :: Documentation 1.0.0-alpha.5 ${project.basedir}/../target/asciidoc/generated io.quarkiverse.jdiameter quarkus-jdiameter-deployment ${project.version} io.quarkus quarkus-maven-plugin ${quarkus.version} true build it.ozimov yaml-properties-maven-plugin initialize read-project-properties ${project.basedir}/../.github/project.yml io.quarkus quarkus-config-doc-maven-plugin ${quarkus.version} true ${project.basedir}/modules/ROOT/pages/includes/ maven-resources-plugin copy-resources generate-resources copy-resources ${project.basedir}/modules/ROOT/pages/includes/ ${project.basedir}/templates/includes attributes.adoc true copy-images prepare-package copy-resources ${project.build.directory}/generated-docs/_images/ ${project.basedir}/modules/ROOT/assets/images/ false default true org.asciidoctor asciidoctor-maven-plugin antora org.antora antora-maven-plugin ${antora.maven.version} true install antora @antora/lunr-extension ================================================ FILE: docs/templates/includes/attributes.adoc ================================================ :project-version: ${release.current-version} :examples-dir: ./../examples/ :authors: Eddie Carpenter :copyright: Apache2 :product-name: Quarkus JDiameter :description: {product-name} documentation :favicon: favicon.svg :email: eddie.carpenter@icloud.com :jee-platform: JBoss Application Server :jee-version: 1.8 :this-issue-tracker-url: https://github.com/quarkisverse/quarkus-jdiameter/issues :this-trunk-source-code-url: https://github.com/quarkisverse/quarkus-jdiameter ================================================ FILE: examples/charging-server-simulator/pom.xml ================================================ 4.0.0 jar org.mobicents restcomm-parent 2.27.32 org.mobicents.servers.diameter.examples charging-server-simulator 1.0.0-SNAPSHOT Restcomm :: Examples :: ${project.artifactId} 1.7.0-SNAPSHOT 1.7.0-SNAPSHOT 1.5.8 3.2.5.GA 1.5.5 org.slf4j slf4j-api ${slf4j.version} org.slf4j slf4j-log4j12 ${slf4j.version} org.jboss.cache jbosscache-core ${jbosscache.version} commons-pool commons-pool ${commons-pool.version} org.slf4j slf4j-api org.slf4j slf4j-log4j12 org.jboss.cache jbosscache-core commons-pool commons-pool org.mobicents.diameter jdiameter-api ${restcomm.diameter.jdiameter.version} org.mobicents.diameter jdiameter-impl ${restcomm.diameter.jdiameter.version} org.mobicents.diameter restcomm-diameter-mux-jar ${restcomm.diameter.mux.version} maven-release org.apache.maven.plugins maven-release-plugin true false release restcomm-dcs-b${buildNumber} org.codehaus.mojo buildnumber-maven-plugin 1.0 validate create {0,date,yyyyMMdd.HHmm} timestamp maven-assembly-plugin src/main/assembly/standalone.xml false org.mobicents.servers.diameter.charging.ChargingServerSimulator config/ install single maven-eclipse-plugin org.mobicents.tools false ${project.artifactId} false scm:git:https://code.google.com/p/jdiameter/ scm:git:https://code.google.com/p/jdiameter/ https://code.google.com/p/jdiameter/ jboss-public-repository-group JBoss Public Maven Repository Group https://repository.jboss.org/nexus/content/groups/public default true never true never ================================================ FILE: examples/charging-server-simulator/src/main/assembly/standalone.xml ================================================ standalone jar false true org.mobicents.diameter:restcomm-diameter-mux-jar org.mobicents.diameter:jdiameter-api org.mobicents.diameter:jdiameter-impl org.slf4j:slf4j-api org.slf4j:slf4j-log4j12 log4j:log4j commons-pool:commons-pool org.picocontainer:picocontainer target/classes ================================================ FILE: examples/charging-server-simulator/src/main/java/org/mobicents/servers/diameter/charging/ChargingServerSimulator.java ================================================ package org.mobicents.servers.diameter.charging; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Properties; import java.util.concurrent.TimeUnit; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.EventListener; import org.jdiameter.api.InternalException; import org.jdiameter.api.Mode; import org.jdiameter.api.Network; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.Peer; import org.jdiameter.api.Request; import org.jdiameter.api.ResultCode; import org.jdiameter.api.app.AppAnswerEvent; import org.jdiameter.api.app.AppRequestEvent; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.events.ReAuthAnswer; import org.jdiameter.api.auth.events.ReAuthRequest; import org.jdiameter.api.cca.ClientCCASession; import org.jdiameter.api.cca.ServerCCASession; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.impl.app.cca.CCASessionFactoryImpl; import org.jdiameter.common.impl.app.cca.JCreditControlAnswerImpl; import org.jdiameter.server.impl.app.cca.ServerCCASessionImpl; import org.mobicents.diameter.dictionary.AvpDictionary; import org.mobicents.servers.diameter.utils.DiameterUtilities; import org.mobicents.servers.diameter.utils.StackCreator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Mobicents Diameter Charging Server Simulator. * * @author Alexandre Mendonca */ public class ChargingServerSimulator extends CCASessionFactoryImpl implements NetworkReqListener, EventListener { private static final Logger logger = LoggerFactory.getLogger(ChargingServerSimulator.class); private static final Object[] EMPTY_ARRAY = new Object[]{}; private ApplicationId roAppId = ApplicationId.createByAuthAppId(10415L, 4L); private HashMap accounts = new HashMap(); private HashMap reserved = new HashMap(); /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { new ChargingServerSimulator(); } StackCreator stackCreator = null; public ChargingServerSimulator() throws Exception { super(); AvpDictionary.INSTANCE.parseDictionary(this.getClass().getClassLoader().getResourceAsStream("dictionary.xml")); try { String config = readFile(this.getClass().getClassLoader().getResourceAsStream("config-server.xml")); this.stackCreator = new StackCreator(config, this, this, "Server", true); Network network = this.stackCreator.unwrap(Network.class); network.addNetworkReqListener(this, roAppId); network.addNetworkReqListener(this, ApplicationId.createByAuthAppId(0, 4)); this.stackCreator.start(Mode.ALL_PEERS, 30000, TimeUnit.MILLISECONDS); printLogo(); sessionFactory = (ISessionFactory) stackCreator.getSessionFactory(); init(sessionFactory); // damn.. this doesn't looks good sessionFactory.registerAppFacory(ServerCCASession.class, this); sessionFactory.registerAppFacory(ClientCCASession.class, this); // Read users from properties file Properties properties = new Properties(); try { InputStream is = this.getClass().getClassLoader().getResourceAsStream("accounts.properties"); if (is == null) { throw new IOException("InputStream is null"); } properties.load(is); for (Object property : properties.keySet()) { String accountName = (String) property; String balance = properties.getProperty(accountName, "0"); if (logger.isInfoEnabled()) { logger.info("Provisioned user '" + accountName + "' with [" + balance + "] units."); } accounts.put(accountName, Long.valueOf(balance)); } } catch (IOException e) { System.err.println("Failed to read 'accounts.properties' file. Aborting."); System.exit(-1); } } catch (Exception e) { logger.error("Failure initializing Mobicents Diameter Ro/Rf Server Simulator", e); } } private void printLogo() { if (logger.isInfoEnabled()) { Properties sysProps = System.getProperties(); String osLine = sysProps.getProperty("os.name") + "/" + sysProps.getProperty("os.arch"); String javaLine = sysProps.getProperty("java.vm.vendor") + " " + sysProps.getProperty("java.vm.name") + " " + sysProps.getProperty("java.vm.version"); Peer localPeer = stackCreator.getMetaData().getLocalPeer(); String diameterLine = localPeer.getProductName() + " (" + localPeer.getUri() + " @ " + localPeer.getRealmName() + ")"; logger.info("==============================================================================="); logger.info(""); logger.info("== Mobicents Diameter Ro/Rf Server Simulator (" + osLine + ")" ); logger.info(""); logger.info("== " + javaLine); logger.info(""); logger.info("== " + diameterLine); logger.info(""); logger.info("==============================================================================="); } } @Override public Answer processRequest(Request request) { if (logger.isInfoEnabled()) { logger.info("<< Received Request [" + request + "]"); } try { ServerCCASessionImpl session = (sessionFactory).getNewAppSession(request.getSessionId(), ApplicationId.createByAuthAppId(0, 4), ServerCCASession.class, EMPTY_ARRAY); session.processRequest(request); } catch (InternalException e) { logger.error(">< Failure handling received request.", e); } return null; } @Override public void receivedSuccessMessage(Request request, Answer answer) { if (logger.isInfoEnabled()) { logger.info("<< Received Success Message for Request [" + request + "] and Answer [" + answer + "]"); } } @Override public void timeoutExpired(Request request) { if (logger.isInfoEnabled()) { logger.info("<< Received Timeout for Request [" + request + "]"); } } @Override public void doCreditControlAnswer(ClientCCASession session, JCreditControlRequest request, JCreditControlAnswer answer) throws InternalException { // Do nothing. } @Override public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException { // Do nothing. } @Override public void doReAuthRequest(ClientCCASession session, ReAuthRequest request) throws InternalException { // Do nothing. } @Override public void doCreditControlRequest(ServerCCASession session, JCreditControlRequest request) throws InternalException { AvpSet ccrAvps = request.getMessage().getAvps(); switch (request.getRequestTypeAVPValue()) { // INITIAL_REQUEST 1 case 1: // UPDATE_REQUEST 2 case 2: if (logger.isInfoEnabled()) { logger.info("<< Received Credit-Control-Request [" + (request.getRequestTypeAVPValue() == 1 ? "INITIAL" : "UPDATE") + "]"); } JCreditControlAnswer cca = null; try { long requestedUnits = ccrAvps.getAvp(Avp.REQUESTED_SERVICE_UNIT).getGrouped().getAvp(Avp.CC_TIME).getInteger32(); String subscriptionId = ccrAvps.getAvp(Avp.SUBSCRIPTION_ID).getGrouped().getAvp(Avp.SUBSCRIPTION_ID_DATA).getUTF8String(); String serviceContextId = ccrAvps.getAvp(Avp.SERVICE_CONTEXT_ID).getUTF8String(); if (logger.isInfoEnabled()) { logger.info(">> '" + subscriptionId + "' requested " + requestedUnits + " units for '" + serviceContextId + "'."); } Long balance = accounts.get(subscriptionId); if (balance != null) { if (balance <= 0) { // DIAMETER_CREDIT_LIMIT_REACHED 4012 // The credit-control server denies the service request because the // end user's account could not cover the requested service. If the // CCR contained used-service-units they are deducted, if possible. cca = createCCA(session, request, -1, 4012); if (logger.isInfoEnabled()) { logger.info("<> '" + subscriptionId + "' has insufficient credit units. Rejecting."); } } else { // Check if not first request, should have Used-Service-Unit AVP if (ccrAvps.getAvp(Avp.CC_REQUEST_NUMBER) != null && ccrAvps.getAvp(Avp.CC_REQUEST_NUMBER).getUnsigned32() >= 1) { Avp usedServiceUnit = ccrAvps.getAvp(Avp.USED_SERVICE_UNIT); if (usedServiceUnit != null) { Long wereReserved = reserved.remove(subscriptionId + "_" + serviceContextId); wereReserved = wereReserved == null ? 0 : wereReserved; long wereUsed = usedServiceUnit.getGrouped().getAvp(Avp.CC_TIME).getUnsigned32(); long remaining = wereReserved - wereUsed; if (logger.isInfoEnabled()) { logger.info(">> '" + subscriptionId + "' had " + wereReserved + " reserved units, " + wereUsed + " units were used." + " (rem: " + remaining + ")."); } balance += remaining; } } long grantedUnits = Math.min(requestedUnits, balance); cca = createCCA(session, request, grantedUnits, ResultCode.SUCCESS); reserved.put(subscriptionId + "_" + serviceContextId, grantedUnits); balance -= grantedUnits; if (logger.isInfoEnabled()) { logger.info(">> '" + subscriptionId + "' Balance: " + (balance + grantedUnits) + " // Available(" + balance + ") Reserved(" + grantedUnits + ")"); } accounts.put(subscriptionId, balance); // Check if the user has no more credit if (balance <= 0) { // 8.34. Final-Unit-Indication AVP // // The Final-Unit-Indication AVP (AVP Code 430) is of type Grouped and // indicates that the Granted-Service-Unit AVP in the Credit-Control- // Answer, or in the AA answer, contains the final units for the // service. After these units have expired, the Diameter credit-control // client is responsible for executing the action indicated in the // Final-Unit-Action AVP (see section 5.6). // // If more than one unit type is received in the Credit-Control-Answer, // the unit type that first expired SHOULD cause the credit-control // client to execute the specified action. // // In the first interrogation, the Final-Unit-Indication AVP with // Final-Unit-Action REDIRECT or RESTRICT_ACCESS can also be present // with no Granted-Service-Unit AVP in the Credit-Control-Answer or in // the AA answer. This indicates to the Diameter credit-control client // to execute the specified action immediately. If the home service // provider policy is to terminate the service, naturally, the server // SHOULD return the appropriate transient failure (see section 9.1) in // order to implement the policy-defined action. // // The Final-Unit-Action AVP defines the behavior of the service element // when the user's account cannot cover the cost of the service and MUST // always be present if the Final-Unit-Indication AVP is included in a // command. // // If the Final-Unit-Action AVP is set to TERMINATE, no other AVPs MUST // be present. // // If the Final-Unit-Action AVP is set to REDIRECT at least the // Redirect-Server AVP MUST be present. The Restriction-Filter-Rule AVP // or the Filter-Id AVP MAY be present in the Credit-Control-Answer // message if the user is also allowed to access other services that are // not accessible through the address given in the Redirect-Server AVP. // // If the Final-Unit-Action AVP is set to RESTRICT_ACCESS, either the // Restriction-Filter-Rule AVP or the Filter-Id AVP SHOULD be present. // // The Filter-Id AVP is defined in [NASREQ]. The Filter-Id AVP can be // used to reference an IP filter list installed in the access device by // means other than the Diameter credit-control application, e.g., // locally configured or configured by another entity. // // The Final-Unit-Indication AVP is defined as follows (per the // grouped-avp-def of RFC 3588 [DIAMBASE]): // // Final-Unit-Indication ::= < AVP Header: 430 > // { Final-Unit-Action } // *[ Restriction-Filter-Rule ] // *[ Filter-Id ] // [ Redirect-Server ] AvpSet finalUnitIndicationAvp = cca.getMessage().getAvps().addGroupedAvp(Avp.FINAL_UNIT_INDICATION); // 8.35. Final-Unit-Action AVP // // The Final-Unit-Action AVP (AVP Code 449) is of type Enumerated and // indicates to the credit-control client the action to be taken when // the user's account cannot cover the service cost. // // The Final-Unit-Action can be one of the following: // // TERMINATE 0 // The credit-control client MUST terminate the service session. // This is the default handling, applicable whenever the credit- // control client receives an unsupported Final-Unit-Action value, // and it MUST be supported by all the Diameter credit-control client // implementations conforming to this specification. // // REDIRECT 1 // The service element MUST redirect the user to the address // specified in the Redirect-Server-Address AVP. The redirect action // is defined in section 5.6.2. // // RESTRICT_ACCESS 2 // The access device MUST restrict the user access according to the // IP packet filters defined in the Restriction-Filter-Rule AVP or // according to the IP packet filters identified by the Filter-Id // AVP. All the packets not matching the filters MUST be dropped // (see section 5.6.3). finalUnitIndicationAvp.addAvp(Avp.FINAL_UNIT_ACTION, 0); } } } else { // DIAMETER_USER_UNKNOWN 5030 // The specified end user is unknown in the credit-control server. cca = createCCA(session, request, -1, 5030); cca.getMessage().setError(true); if (logger.isInfoEnabled()) { logger.info("<> '" + subscriptionId + "' is not provisioned in this server. Rejecting."); } } //cca.getMessage().getAvps().addAvp(Avp.SERVICE_CONTEXT_ID, serviceContextId, false); session.sendCreditControlAnswer(cca); } catch (Exception e) { logger.error(">< Failure processing Credit-Control-Request [" + (request.getRequestTypeAVPValue() == 1 ? "INITIAL" : "UPDATE") + "]", e); } break; // TERMINATION_REQUEST 3 case 3: if (logger.isInfoEnabled()) { logger.info("<< Received Credit-Control-Request [TERMINATION]"); } try { String subscriptionId = ccrAvps.getAvp(Avp.SUBSCRIPTION_ID).getGrouped().getAvp(Avp.SUBSCRIPTION_ID_DATA).getUTF8String(); String serviceContextId = ccrAvps.getAvp(Avp.SERVICE_CONTEXT_ID).getUTF8String(); if (logger.isInfoEnabled()) { logger.info(">> '" + subscriptionId + "' requested service termination for '" + serviceContextId + "'."); } Long balance = accounts.get(subscriptionId); if (ccrAvps.getAvp(Avp.CC_REQUEST_NUMBER) != null && ccrAvps.getAvp(Avp.CC_REQUEST_NUMBER).getUnsigned32() >= 1) { Avp usedServiceUnit = ccrAvps.getAvp(Avp.USED_SERVICE_UNIT); if (usedServiceUnit != null) { long wereReserved = reserved.remove(subscriptionId + "_" + serviceContextId); long wereUsed = usedServiceUnit.getGrouped().getAvp(Avp.CC_TIME).getUnsigned32(); long remaining = wereReserved - wereUsed; if (logger.isInfoEnabled()) { logger.info(">> '" + subscriptionId + "' had " + wereReserved + " reserved units, " + wereUsed + " units were used." + " (non-used: " + remaining + ")."); } balance += remaining; } } if (logger.isInfoEnabled()) { logger.info(">> '" + subscriptionId + "' Balance: " + balance + " // Available(" + balance + ") Reserved(0)"); } accounts.put(subscriptionId, balance); cca = createCCA(session, request, -1, ResultCode.SUCCESS); // 8.7. Cost-Information AVP // // The Cost-Information AVP (AVP Code 423) is of type Grouped, and it is // used to return the cost information of a service, which the credit- // control client can transfer transparently to the end user. The // included Unit-Value AVP contains the cost estimate (always type of // money) of the service, in the case of price enquiry, or the // accumulated cost estimation, in the case of credit-control session. // // The Currency-Code specifies in which currency the cost was given. // The Cost-Unit specifies the unit when the service cost is a cost per // unit (e.g., cost for the service is $1 per minute). // // When the Requested-Action AVP with value PRICE_ENQUIRY is included in // the Credit-Control-Request command, the Cost-Information AVP sent in // the succeeding Credit-Control-Answer command contains the cost // estimation of the requested service, without any reservation being // made. // // The Cost-Information AVP included in the Credit-Control-Answer // command with the CC-Request-Type set to UPDATE_REQUEST contains the // accumulated cost estimation for the session, without taking any // credit reservation into account. // // The Cost-Information AVP included in the Credit-Control-Answer // command with the CC-Request-Type set to EVENT_REQUEST or // TERMINATION_REQUEST contains the estimated total cost for the // requested service. // // It is defined as follows (per the grouped-avp-def of // RFC 3588 [DIAMBASE]): // // Cost-Information ::= < AVP Header: 423 > // { Unit-Value } // { Currency-Code } // [ Cost-Unit ] // 7.2.133 Remaining-Balance AVP // // The Remaining-Balance AVP (AVPcode 2021) is of type Grouped and // provides information about the remaining account balance of the // subscriber. // // It has the following ABNF grammar: // Remaining-Balance :: = < AVP Header: 2021 > // { Unit-Value } // { Currency-Code } // We use no money notion ... maybe later. // AvpSet costInformation = ccaAvps.addGroupedAvp(423); session.sendCreditControlAnswer(cca); } catch (Exception e) { logger.error(">< Failure processing Credit-Control-Request [TERMINATION]", e); } break; // EVENT_REQUEST 4 case 4: if (logger.isInfoEnabled()) { logger.info("<< Received Credit-Control-Request [EVENT]"); } break; default: break; } } @Override public void doReAuthAnswer(ServerCCASession session, ReAuthRequest request, ReAuthAnswer answer) throws InternalException { // Do Nothing. } @Override public void sessionSupervisionTimerExpired(ServerCCASession session) { // Do Nothing. } @Override public void denyAccessOnTxExpire(ClientCCASession clientCCASessionImpl) { // Do Nothing. } @Override public void txTimerExpired(ClientCCASession session) { // Do Nothing. } private JCreditControlAnswer createCCA(ServerCCASession session, JCreditControlRequest request, long grantedUnits, long resultCode) throws InternalException, AvpDataException { JCreditControlAnswerImpl answer = new JCreditControlAnswerImpl((Request) request.getMessage(), resultCode); AvpSet ccrAvps = request.getMessage().getAvps(); AvpSet ccaAvps = answer.getMessage().getAvps(); // ::= < Diameter Header: 272, PXY > // < Session-Id > // { Result-Code } // { Origin-Host } // { Origin-Realm } // { Auth-Application-Id } // { CC-Request-Type } // Using the same as the one present in request ccaAvps.addAvp(ccrAvps.getAvp(Avp.CC_REQUEST_TYPE)); // { CC-Request-Number } // Using the same as the one present in request ccaAvps.addAvp(ccrAvps.getAvp(Avp.CC_REQUEST_NUMBER)); // [ User-Name ] // [ CC-Session-Failover ] // [ CC-Sub-Session-Id ] // [ Acct-Multi-Session-Id ] // [ Origin-State-Id ] // [ Event-Timestamp ] // [ Granted-Service-Unit ] // 8.17. Granted-Service-Unit AVP // // Granted-Service-Unit AVP (AVP Code 431) is of type Grouped and // contains the amount of units that the Diameter credit-control client // can provide to the end user until the service must be released or the // new Credit-Control-Request must be sent. A client is not required to // implement all the unit types, and it must treat unknown or // unsupported unit types in the answer message as an incorrect CCA // answer. In this case, the client MUST terminate the credit-control // session and indicate in the Termination-Cause AVP reason // DIAMETER_BAD_ANSWER. // // The Granted-Service-Unit AVP is defined as follows (per the grouped- // avp-def of RFC 3588 [DIAMBASE]): // // Granted-Service-Unit ::= < AVP Header: 431 > // [ Tariff-Time-Change ] // [ CC-Time ] // [ CC-Money ] // [ CC-Total-Octets ] // [ CC-Input-Octets ] // [ CC-Output-Octets ] // [ CC-Service-Specific-Units ] // *[ AVP ] if (grantedUnits >= 0) { AvpSet gsuAvp = ccaAvps.addGroupedAvp(Avp.GRANTED_SERVICE_UNIT); // Fetch AVP/Value from Request // gsuAvp.addAvp(ccrAvps.getAvp(Avp.REQUESTED_SERVICE_UNIT).getGrouped().getAvp(Avp.CC_TIME)); gsuAvp.addAvp(Avp.CC_TIME, grantedUnits, true); } // *[ Multiple-Services-Credit-Control ] // [ Cost-Information] // [ Final-Unit-Indication ] // [ Check-Balance-Result ] // [ Credit-Control-Failure-Handling ] // [ Direct-Debiting-Failure-Handling ] // [ Validity-Time] // *[ Redirect-Host] // [ Redirect-Host-Usage ] // [ Redirect-Max-Cache-Time ] // *[ Proxy-Info ] // *[ Route-Record ] // *[ Failed-AVP ] // *[ AVP ] if (logger.isInfoEnabled()) { logger.info(">> Created Credit-Control-Answer."); DiameterUtilities.printMessage(answer.getMessage()); } return answer; } private static String readFile(InputStream is) throws IOException { /*FileInputStream stream = new FileInputStream(is); try { FileChannel fc = stream.getChannel(); MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); // Instead of using default, pass in a decoder. return Charset.defaultCharset().decode(bb).toString(); } finally { stream.close(); }*/ BufferedInputStream bin = new BufferedInputStream(is); byte[] contents = new byte[1024]; int bytesRead = 0; String strFileContents; StringBuilder sb = new StringBuilder(); while ( (bytesRead = bin.read(contents)) != -1) { strFileContents = new String(contents, 0, bytesRead); sb.append(strFileContents); } return sb.toString(); } } ================================================ FILE: examples/charging-server-simulator/src/main/java/org/mobicents/servers/diameter/charging/listeners/RoClientListener.java ================================================ package org.mobicents.servers.diameter.charging.listeners; public interface RoClientListener { /** * Callback method for successful request for credit units. * * @param amount the amount of granted units * @param finalUnits true if these are the last units * @throws Exception */ void creditGranted(long amount, boolean finalUnits) throws Exception; /** * Callback method for unsuccessful request for credit units. * * @param failureCode the code specifying why it failed * @throws Exception */ void creditDenied(int failureCode) throws Exception; /** * Callback method for end of credit. Service should be terminated. * * @throws Exception */ void creditTerminated() throws Exception; } ================================================ FILE: examples/charging-server-simulator/src/main/java/org/mobicents/servers/diameter/utils/DiameterUtilities.java ================================================ package org.mobicents.servers.diameter.utils; import org.apache.log4j.Logger; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Message; import org.jdiameter.api.validation.AvpRepresentation; import org.jdiameter.api.validation.Dictionary; import org.jdiameter.common.impl.validation.DictionaryImpl; public class DiameterUtilities { private static Logger logger = Logger.getLogger(DiameterUtilities.class); public static Dictionary AVP_DICTIONARY = DictionaryImpl.INSTANCE; public static void printMessage(Message message) { String reqFlag = message.isRequest() ? "R" : "A"; String flags = reqFlag += message.isError() ? " | E" : ""; if (logger.isInfoEnabled()) { logger.info("Message [" + flags + "] Command-Code: " + message.getCommandCode() + " / E2E(" + message.getEndToEndIdentifier() + ") / HbH(" + message.getHopByHopIdentifier() + ")"); logger.info("- - - - - - - - - - - - - - - - AVPs - - - - - - - - - - - - - - - -"); printAvps(message.getAvps()); } } public static void printAvps(AvpSet avps) { printAvps(avps, ""); } public static void printAvps(AvpSet avps, String indentation) { for (Avp avp : avps) { AvpRepresentation avpRep = AVP_DICTIONARY.getAvp(avp.getCode(), avp.getVendorId()); Object avpValue = null; boolean isGrouped = false; try { String avpType = AVP_DICTIONARY.getAvp(avp.getCode(), avp.getVendorId()).getType(); if ("Integer32".equals(avpType) || "AppId".equals(avpType)) { avpValue = avp.getInteger32(); } else if ("Unsigned32".equals(avpType) || "VendorId".equals(avpType)) { avpValue = avp.getUnsigned32(); } else if ("Float64".equals(avpType)) { avpValue = avp.getFloat64(); } else if ("Integer64".equals(avpType)) { avpValue = avp.getInteger64(); } else if ("Time".equals(avpType)) { avpValue = avp.getTime(); } else if ("Unsigned64".equals(avpType)) { avpValue = avp.getUnsigned64(); } else if ("Grouped".equals(avpType)) { avpValue = ""; isGrouped = true; } else { avpValue = avp.getUTF8String().replaceAll("\r", "").replaceAll("\n", ""); } } catch (Exception ignore) { try { avpValue = avp.getUTF8String().replaceAll("\r", "").replaceAll("\n", ""); } catch (AvpDataException e) { avpValue = avp.toString(); } } String avpLine = indentation + avp.getCode() + ": " + avpRep.getName(); while (avpLine.length() < 50) { avpLine += avpLine.length() % 2 == 0 ? "." : " "; } avpLine += avpValue; logger.info(avpLine); if (isGrouped) { try { printAvps(avp.getGrouped(), indentation + " "); } catch (AvpDataException e) { // Failed to ungroup... ignore then... } } } } } ================================================ FILE: examples/charging-server-simulator/src/main/java/org/mobicents/servers/diameter/utils/StackCreator.java ================================================ package org.mobicents.servers.diameter.utils; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.Set; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Configuration; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.MetaData; import org.jdiameter.api.Mode; import org.jdiameter.api.Network; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.Request; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.Stack; import org.jdiameter.server.impl.StackImpl; import org.jdiameter.server.impl.helpers.XMLConfiguration; public class StackCreator extends StackImpl implements Stack { private static Logger logger = Logger.getLogger(StackCreator.class); private Stack stack = null; public StackCreator(Configuration config, NetworkReqListener networkReqListener, EventListener eventListener, String identifier, Boolean isServer) { super(); this.stack = new org.jdiameter.server.impl.StackImpl(); try { this.stack.init(config); // Let it stabilize... Thread.sleep(500); Network network = stack.unwrap(Network.class); Set appIds = stack.getMetaData().getLocalPeer().getCommonApplications(); for (ApplicationId appId : appIds) { if (logger.isInfoEnabled()) { logger.info("Diameter " + identifier + " :: Adding Listener for [" + appId + "]."); } network.addNetworkReqListener(networkReqListener, appId); } if (logger.isInfoEnabled()) { logger.info("Diameter " + identifier + " :: Supporting " + appIds.size() + " applications."); } } catch (Exception e) { logger.error("Failure creating stack '" + identifier + "'", e); } } public StackCreator(InputStream streamConfig, NetworkReqListener networkReqListener, EventListener eventListener, String dooer, Boolean isServer) throws Exception { this(isServer ? new XMLConfiguration(streamConfig) : new org.jdiameter.client.impl.helpers.XMLConfiguration(streamConfig), networkReqListener, eventListener, dooer, isServer); } public StackCreator(String stringConfig, NetworkReqListener networkReqListener, EventListener eventListener, String dooer, Boolean isServer) throws Exception { this(isServer ? new XMLConfiguration(new ByteArrayInputStream(stringConfig.getBytes())) : new org.jdiameter.client.impl.helpers.XMLConfiguration( new ByteArrayInputStream(stringConfig.getBytes())), networkReqListener, eventListener, dooer, isServer); } @Override public void destroy() { stack.destroy(); } @Override public java.util.logging.Logger getLogger() { return stack.getLogger(); } @Override public MetaData getMetaData() { return stack.getMetaData(); } @Override public SessionFactory getSessionFactory() throws IllegalDiameterStateException { return stack.getSessionFactory(); } @Override public SessionFactory init(Configuration config) throws IllegalDiameterStateException, InternalException { return stack.init(config); } @Override public boolean isActive() { return stack.isActive(); } @Override public boolean isWrapperFor(Class iface) throws InternalException { return stack.isWrapperFor(iface); } @Override public void start() throws IllegalDiameterStateException, InternalException { stack.start(); } @Override public void start(Mode mode, long timeout, TimeUnit unit) throws IllegalDiameterStateException, InternalException { stack.start(mode, timeout, unit); } @Override public void stop(long timeout, TimeUnit unit, int disconnectReason) throws IllegalDiameterStateException, InternalException { stack.stop(timeout, unit, disconnectReason); } @Override public T unwrap(Class iface) throws InternalException { return stack.unwrap(iface); } } ================================================ FILE: examples/charging-server-simulator/src/main/resources/accounts.properties ================================================ sip\:alexandre@mobicents.org = 45 sip\:bbaranowb@mobicents.org = 123 ================================================ FILE: examples/charging-server-simulator/src/main/resources/config-server.xml ================================================ ================================================ FILE: examples/charging-server-simulator/src/main/resources/dictionary.xml ================================================ /> ================================================ FILE: examples/charging-server-simulator/src/main/resources/log4j.properties ================================================ # Set root logger level to DEBUG and its only appender to A1. log4j.rootLogger=DEBUG, A1 # A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.ConsoleAppender # File #log4j.appender.R=org.apache.log4j.RollingFileAppender #log4j.appender.R.File=log4j.log #log4j.appender.R.File=/home/abhayani/workarea/mobicents/svn/trunk/servers/media/test-suite/core/target/mylogfile.log # Archive log files (one backup file here) #log4j.appender.R.MaxBackupIndex=1 #log4j.appender.R.layout=org.apache.log4j.PatternLayout #log4j.appender.R.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout #log4j.appender.A1.layout.ConversionPattern=%d %-5p [%t] %c %x - %m%n log4j.appender.A1.layout.ConversionPattern=%d %-5p %c{1} - %m%n log4j.logger.org.mobicents.tests.diameter=DEBUG log4j.category.org.jdiameter=INFO log4j.category.jdiameter.statistic=INFO log4j.category.org.jdiameter.common.impl.validation=INFO ================================================ FILE: examples/guide1/bin/crun.sh ================================================ #!/bin/sh # In case we need it. cygwin=false; darwin=false; linux=false; case "`uname`" in CYGWIN*) cygwin=true ;; Darwin*) darwin=true ;; Linux) linux=true ;; esac DIRNAME=`dirname $0` PROGNAME=`basename $0` # Force IPv4 on Linux systems since IPv6 doesn't work correctly with jdk5 and lower if [ "$linux" = "true" ]; then JAVA_OPTS="$JAVA_OPTS -Djava.net.preferIPv4Stack=true" fi # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` [ -n "$JAVAC_JAR" ] && JAVAC_JAR=`cygpath --unix "$JAVAC_JAR"` fi # Setup TEST_CORE if [ "x$TEST_CORE" = "x" ]; then # get the full path (without any relative bits) TEST_CORE=`cd $DIRNAME/..; pwd` fi export TEST_CORE #Setup the JVM if [ "x$JAVA" = "x" ]; then if [ "x$JAVA_HOME" != "x" ]; then JAVA="$JAVA_HOME/bin/java" else JAVA="java" fi fi RUN_CLASSPATH="$TEST_CORE/target/example1-1.7.0-SNAPSHOT-jar-with-dependencies.jar" # For Cygwin, switch paths to Windows format before running java if $cygwin; then TEST_CORE=`cygpath --path --windows "$TEST_CORE"` JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` RUN_CLASSPATH=`cygpath --path --windows "$RUN_CLASSPATH"` fi # warn() { echo "${PROGNAME}: $*" } # # Helper to puke. # die() { warn $* exit 1 } usage(){ echo "Usage:" echo "bin.sh [OPTIONS] --testtype TestType" echo "Where options can be:" echo "--localaddr : local address, default is 127.0.0.1" echo "--remoteaddr : remote address, default is 127.0.0.1" echo "--localpport : local port, default is 2428" echo "--remoteport : remote port, default is 2427" echo "--concurrentcalls : concurrent calls, default is -1, which means unbound" echo "--maxcalls : max calls, default is -1, which means unbound" echo "--datadir : data dump directory, default is ./datadump. IN case of offline runs, it must point to valid test, like: /datadump/1231463412" echo "--audiofile : audio file url, if requried, default is file:/...../target/audio/ulaw_13s.wav" echo "--audiocodec : audio codec to be used if requried, default is \'0 pcmu/8000\', value should be specifiedd in \'\'" echo "--testtype : test type, currently there is only one available: AnnTest" echo "--maxfail : specifies how many calls may fail until testtool will stop sending requests to server, default is -1, which means unbound" echo "--graph : It makes test case produce graphic files and present some txt output. Graphic files depend on testcase, some do not support graphic. If there is no value, test case picks one call arbitrary, otherwise it performs this operation for specific call. Argumetn must match call sequence." echo "--callduration : specifies how long test runs(in milliseconds), default is 2500 " echo "--cps : specifies calls per second, default is 1 " echo "--usage : print cli usage directly from CLI runner" echo "example options part: --localaddress=127.0.0.1 --localport=2499 --concurentcalls=12 --audiocodec=\'8 pcma/8000\' --testtype=AnnTest" } executeTest(){ # Display our environment echo "=========================================================================" echo "" echo " JBoss Bootstrap Environment" echo "" echo " RUN_HOME : $TEST_CORE" echo "" echo " JAVA : $JAVA" echo "" echo " JAVA_OPTS: $JAVA_OPTS" echo "" echo " CLASSPATH: $RUN_CLASSPATH" echo "" echo " MAVEN : mvn" echo "" echo " OPTS : $*" echo "" echo "=========================================================================" echo "" echo "Preparing test tool jar..." #mvn -f $TEST_CORE/pom.xml clean install #mvn -f $TEST_CORE/pom.xml install #mvn -f $TEST_CORE/pom.xml install -Pbuild echo "" echo "=========================================================================" echo "" echo "JAR and dependencies are ready, executing test session" echo "" echo "=========================================================================" "$JAVA" $JAVA_OPTS \ -classpath "$RUN_CLASSPATH" \ org.example.client.ExampleClient $* } if [ "$#" = "0" ]; then executeTest "--usage" #usage die fi executeTest $* ================================================ FILE: examples/guide1/bin/srun.sh ================================================ #!/bin/sh # In case we need it. cygwin=false; darwin=false; linux=false; case "`uname`" in CYGWIN*) cygwin=true ;; Darwin*) darwin=true ;; Linux) linux=true ;; esac DIRNAME=`dirname $0` PROGNAME=`basename $0` # Force IPv4 on Linux systems since IPv6 doesn't work correctly with jdk5 and lower if [ "$linux" = "true" ]; then JAVA_OPTS="$JAVA_OPTS -Djava.net.preferIPv4Stack=true" fi # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` [ -n "$JAVAC_JAR" ] && JAVAC_JAR=`cygpath --unix "$JAVAC_JAR"` fi # Setup TEST_CORE if [ "x$TEST_CORE" = "x" ]; then # get the full path (without any relative bits) TEST_CORE=`cd $DIRNAME/..; pwd` fi export TEST_CORE #Setup the JVM if [ "x$JAVA" = "x" ]; then if [ "x$JAVA_HOME" != "x" ]; then JAVA="$JAVA_HOME/bin/java" else JAVA="java" fi fi RUN_CLASSPATH="$TEST_CORE/target/run/example1.jar.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/xml-apis.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/run/slf4j-log4j12.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/run/slf4j-api.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/run/java-getopt.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/run/picocontainer.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/run/junit.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/run/jdiameter-impl.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/run/jdiameter-api.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/run/log4j.jar" RUN_CLASSPATH="$RUN_CLASSPATH:$TEST_CORE/target/run/mux.jar" # For Cygwin, switch paths to Windows format before running java if $cygwin; then TEST_CORE=`cygpath --path --windows "$TEST_CORE"` JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` RUN_CLASSPATH=`cygpath --path --windows "$RUN_CLASSPATH"` fi # warn() { echo "${PROGNAME}: $*" } # # Helper to puke. # die() { warn $* exit 1 } usage(){ echo "Usage:" echo "bin.sh [OPTIONS] --testtype TestType" echo "Where options can be:" echo "--localaddr : local address, default is 127.0.0.1" echo "--remoteaddr : remote address, default is 127.0.0.1" echo "--localpport : local port, default is 2428" echo "--remoteport : remote port, default is 2427" echo "--concurrentcalls : concurrent calls, default is -1, which means unbound" echo "--maxcalls : max calls, default is -1, which means unbound" echo "--datadir : data dump directory, default is ./datadump. IN case of offline runs, it must point to valid test, like: /datadump/1231463412" echo "--audiofile : audio file url, if requried, default is file:/...../target/audio/ulaw_13s.wav" echo "--audiocodec : audio codec to be used if requried, default is \'0 pcmu/8000\', value should be specifiedd in \'\'" echo "--testtype : test type, currently there is only one available: AnnTest" echo "--maxfail : specifies how many calls may fail until testtool will stop sending requests to server, default is -1, which means unbound" echo "--graph : It makes test case produce graphic files and present some txt output. Graphic files depend on testcase, some do not support graphic. If there is no value, test case picks one call arbitrary, otherwise it performs this operation for specific call. Argumetn must match call sequence." echo "--callduration : specifies how long test runs(in milliseconds), default is 2500 " echo "--cps : specifies calls per second, default is 1 " echo "--usage : print cli usage directly from CLI runner" echo "example options part: --localaddress=127.0.0.1 --localport=2499 --concurentcalls=12 --audiocodec=\'8 pcma/8000\' --testtype=AnnTest" } executeTest(){ # Display our environment echo "=========================================================================" echo "" echo " JBoss Bootstrap Environment" echo "" echo " RUN_HOME : $TEST_CORE" echo "" echo " JAVA : $JAVA" echo "" echo " JAVA_OPTS: $JAVA_OPTS" echo "" echo " CLASSPATH: $RUN_CLASSPATH" echo "" echo " MAVEN : mvn" echo "" echo " OPTS : $*" echo "" echo "=========================================================================" echo "" echo "Preparing test tool jar..." #mvn -f $TEST_CORE/pom.xml clean install mvn -f $TEST_CORE/pom.xml install mvn -f $TEST_CORE/pom.xml install -Pbuild echo "" echo "=========================================================================" echo "" echo "JAR and dependencies are ready, executing test session" echo "" echo "=========================================================================" "$JAVA" $JAVA_OPTS \ -classpath "$RUN_CLASSPATH" \ org.example.server.ExampleServer $* } if [ "$#" = "0" ]; then executeTest "--usage" #usage die fi executeTest $* ================================================ FILE: examples/guide1/pom.xml ================================================ 4.0.0 org.mobicents.diameter diameter-parent 1.7.0-SNAPSHOT org.mobicents.servers.diameter.guide example1 Restcomm :: Guide :: Example 1 :: ${project.artifactId} 1.7.0-SNAPSHOT 1.7.0-SNAPSHOT 1.0.9 1.2 1.5.8 org.mobicents.diameter restcomm-diameter-mux-jar ${restcomm.diameter.mux.version} org.mobicents.diameter jdiameter-api ${restcomm.diameter.jdiameter.version} org.mobicents.diameter jdiameter-impl ${restcomm.diameter.jdiameter.version} picocontainer picocontainer ${picocontainer.version} junit junit ${junit.version} urbanophile java-getopt ${get.opt.version} org.slf4j slf4j-api ${slf4j.version} org.slf4j slf4j-log4j12 ${slf4j.version} maven-assembly-plugin jar-with-dependencies org.example.client.ExampleClient package single default true true build false false ================================================ FILE: examples/guide1/src/main/java/org/example/client/ExampleClient.java ================================================ /* * JBoss, Home of Professional Open Source * Copyright XXXX, Red Hat Middleware LLC, and individual contributors as indicated * by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a full listing * of individual contributors. * 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 General Public License, v. 2.0. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * You should have received a copy of the GNU General Public License, * v. 2.0 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package org.example.client; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Properties; import java.util.Set; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Configuration; import org.jdiameter.api.EventListener; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.MetaData; import org.jdiameter.api.Network; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.Session; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.Stack; import org.jdiameter.api.StackType; import org.jdiameter.server.impl.StackImpl; import org.jdiameter.server.impl.helpers.XMLConfiguration; import org.mobicents.diameter.dictionary.AvpDictionary; import org.mobicents.diameter.dictionary.AvpRepresentation; public class ExampleClient implements EventListener { private static final Logger log = Logger.getLogger(ExampleClient.class); static{ //configure logging. configLog4j(); } private static void configLog4j() { InputStream inStreamLog4j = ExampleClient.class.getClassLoader().getResourceAsStream("log4j.properties"); Properties propertiesLog4j = new Properties(); try { propertiesLog4j.load(inStreamLog4j); PropertyConfigurator.configure(propertiesLog4j); } catch (Exception e) { e.printStackTrace(); }finally { if(inStreamLog4j!=null) { try { inStreamLog4j.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } log.debug("log4j configured"); } //configuration files private static final String configFile = "org/example/client/client-jdiameter-config.xml"; private static final String dictionaryFile = "org/example/client/dictionary.xml"; //our destination private static final String serverHost = "127.0.0.1"; private static final String serverPort = "3868"; private static final String serverURI = "aaa://" + serverHost + ":" + serverPort; //our realm private static final String realmName = "exchange.example.org"; // definition of codes, IDs private static final int commandCode = 686; private static final long vendorID = 66666; private static final long applicationID = 33333; private ApplicationId authAppId = ApplicationId.createByAuthAppId(applicationID); private static final int exchangeTypeCode = 888; private static final int exchangeDataCode = 999; // enum values for Exchange-Type AVP private static final int EXCHANGE_TYPE_INITIAL = 0; private static final int EXCHANGE_TYPE_INTERMEDIATE = 1; private static final int EXCHANGE_TYPE_TERMINATING = 2; //list of data we want to exchange. private static final String[] TO_SEND = new String[] { "I want to get 3 answers", "This is second message", "Bye bye" }; //Dictionary, for informational purposes. private AvpDictionary dictionary = AvpDictionary.INSTANCE; //stack and session factory private Stack stack; private SessionFactory factory; // //////////////////////////////////////// // Objects which will be used in action // // //////////////////////////////////////// private Session session; // session used as handle for communication private int toSendIndex = 0; //index in TO_SEND table private boolean finished = false; //boolean telling if we finished our interaction private void initStack() { if (log.isInfoEnabled()) { log.info("Initializing Stack..."); } InputStream is = null; try { //Parse dictionary, it is used for user friendly info. dictionary.parseDictionary(this.getClass().getClassLoader().getResourceAsStream(dictionaryFile)); log.info("AVP Dictionary successfully parsed."); this.stack = new StackImpl(); //Parse stack configuration is = this.getClass().getClassLoader().getResourceAsStream(configFile); Configuration config = new XMLConfiguration(is); factory = stack.init(config); if (log.isInfoEnabled()) { log.info("Stack Configuration successfully loaded."); } //Print info about applicatio Set appIds = stack.getMetaData().getLocalPeer().getCommonApplications(); log.info("Diameter Stack :: Supporting " + appIds.size() + " applications."); for (org.jdiameter.api.ApplicationId x : appIds) { log.info("Diameter Stack :: Common :: " + x); } is.close(); //Register network req listener, even though we wont receive requests //this has to be done to inform stack that we support application Network network = stack.unwrap(Network.class); network.addNetworkReqListener(new NetworkReqListener() { @Override public Answer processRequest(Request request) { //this wontbe called. return null; } }, this.authAppId); //passing our example app id. } catch (Exception e) { e.printStackTrace(); if (this.stack != null) { this.stack.destroy(); } if (is != null) { try { is.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } return; } MetaData metaData = stack.getMetaData(); //ignore for now. if (metaData.getStackType() != StackType.TYPE_SERVER || metaData.getMinorVersion() <= 0) { stack.destroy(); if (log.isEnabledFor(org.apache.log4j.Level.ERROR)) { log.error("Incorrect driver"); } return; } try { if (log.isInfoEnabled()) { log.info("Starting stack"); } stack.start(); if (log.isInfoEnabled()) { log.info("Stack is running."); } } catch (Exception e) { e.printStackTrace(); stack.destroy(); return; } if (log.isInfoEnabled()) { log.info("Stack initialization successfully completed."); } } /** * @return */ private boolean finished() { return this.finished; } /** * */ private void start() { try { //wait for connection to peer try { Thread.currentThread().sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //do send this.session = this.factory.getNewSession("BadCustomSessionId;YesWeCanPassId;" + System.currentTimeMillis()); sendNextRequest(EXCHANGE_TYPE_INITIAL); } catch (InternalException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalDiameterStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RouteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (OverloadException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void sendNextRequest(int enumType) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { Request r = this.session.createRequest(commandCode, this.authAppId, realmName, serverURI); // here we have all except our custom avps AvpSet requestAvps = r.getAvps(); // code , value , vendor, mandatory,protected,isUnsigned32 // (Enumerated) Avp exchangeType = requestAvps.addAvp(exchangeTypeCode, (long) enumType, vendorID, true, false, true); // value // is // set // on // creation // code , value , vendor, mandatory,protected, isOctetString Avp exchengeData = requestAvps.addAvp(exchangeDataCode, TO_SEND[toSendIndex++], vendorID, true, false, false); // value // is // set // on // creation // send this.session.send(r, this); dumpMessage(r,true); //dump info on console } /* * (non-Javadoc) * * @see org.jdiameter.api.EventListener#receivedSuccessMessage(org.jdiameter * .api.Message, org.jdiameter.api.Message) */ @Override public void receivedSuccessMessage(Request request, Answer answer) { dumpMessage(answer,false); if (answer.getCommandCode() != commandCode) { log.error("Received bad answer: " + answer.getCommandCode()); return; } AvpSet answerAvpSet = answer.getAvps(); Avp exchangeTypeAvp = answerAvpSet.getAvp(exchangeTypeCode, vendorID); Avp exchangeDataAvp = answerAvpSet.getAvp(exchangeDataCode, vendorID); Avp resultAvp = answer.getResultCode(); try { //for bad formatted request. if (resultAvp.getUnsigned32() == 5005 || resultAvp.getUnsigned32() == 5004) { // missing || bad value of avp this.session.release(); this.session = null; log.error("Something wrong happened at server side!"); finished = true; } switch ((int) exchangeTypeAvp.getUnsigned32()) { case EXCHANGE_TYPE_INITIAL: // JIC check; String data = exchangeDataAvp.getUTF8String(); if (data.equals(TO_SEND[toSendIndex - 1])) { // ok :) send next; sendNextRequest(EXCHANGE_TYPE_INTERMEDIATE); } else { log.error("Received wrong Exchange-Data: " + data); } break; case EXCHANGE_TYPE_INTERMEDIATE: // JIC check; data = exchangeDataAvp.getUTF8String(); if (data.equals(TO_SEND[toSendIndex - 1])) { // ok :) send next; sendNextRequest(EXCHANGE_TYPE_TERMINATING); } else { log.error("Received wrong Exchange-Data: " + data); } break; case EXCHANGE_TYPE_TERMINATING: data = exchangeDataAvp.getUTF8String(); if (data.equals(TO_SEND[toSendIndex - 1])) { // good, we reached end of FSM. finished = true; // release session and its resources. this.session.release(); this.session = null; } else { log.error("Received wrong Exchange-Data: " + data); } break; default: log.error("Bad value of Exchange-Type avp: " + exchangeTypeAvp.getUnsigned32()); break; } } catch (AvpDataException e) { // thrown when interpretation of byte[] fails e.printStackTrace(); } catch (InternalException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalDiameterStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RouteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (OverloadException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * (non-Javadoc) * * @see org.jdiameter.api.EventListener#timeoutExpired(org.jdiameter.api. * Message) */ @Override public void timeoutExpired(Request request) { } private void dumpMessage(Message message, boolean sending) { if (log.isInfoEnabled()) { log.info((sending?"Sending ":"Received ") + (message.isRequest() ? "Request: " : "Answer: ") + message.getCommandCode() + "\nE2E:" + message.getEndToEndIdentifier() + "\nHBH:" + message.getHopByHopIdentifier() + "\nAppID:" + message.getApplicationId()); log.info("AVPS["+message.getAvps().size()+"]: \n"); try { printAvps(message.getAvps()); } catch (AvpDataException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private void printAvps(AvpSet avpSet) throws AvpDataException { printAvpsAux(avpSet, 0); } /** * Prints the AVPs present in an AvpSet with a specified 'tab' level * * @param avpSet * the AvpSet containing the AVPs to be printed * @param level * an int representing the number of 'tabs' to make a pretty * print * @throws AvpDataException */ private void printAvpsAux(AvpSet avpSet, int level) throws AvpDataException { String prefix = " ".substring(0, level * 2); for (Avp avp : avpSet) { AvpRepresentation avpRep = AvpDictionary.INSTANCE.getAvp(avp.getCode(), avp.getVendorId()); if (avpRep != null && avpRep.getType().equals("Grouped")) { log.info(prefix + ""); printAvpsAux(avp.getGrouped(), level + 1); log.info(prefix + ""); } else if (avpRep != null) { String value = ""; if (avpRep.getType().equals("Integer32")) value = String.valueOf(avp.getInteger32()); else if (avpRep.getType().equals("Integer64") || avpRep.getType().equals("Unsigned64")) value = String.valueOf(avp.getInteger64()); else if (avpRep.getType().equals("Unsigned32")) value = String.valueOf(avp.getUnsigned32()); else if (avpRep.getType().equals("Float32")) value = String.valueOf(avp.getFloat32()); else //value = avp.getOctetString(); value = new String(avp.getOctetString(), StandardCharsets.UTF_8); log.info(prefix + ""); } } } public static void main(String[] args) { ExampleClient ec = new ExampleClient(); ec.initStack(); ec.start(); while (!ec.finished()) { try { Thread.currentThread().sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } ================================================ FILE: examples/guide1/src/main/java/org/example/server/ExampleServer.java ================================================ /* * JBoss, Home of Professional Open Source * Copyright XXXX, Red Hat Middleware LLC, and individual contributors as indicated * by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a full listing * of individual contributors. * 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 General Public License, v. 2.0. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * You should have received a copy of the GNU General Public License, * v. 2.0 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package org.example.server; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Properties; import java.util.Set; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.Avp; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.MetaData; import org.jdiameter.api.Network; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.api.Request; import org.jdiameter.api.Session; import org.jdiameter.api.SessionFactory; import org.jdiameter.api.Stack; import org.jdiameter.api.StackType; import org.jdiameter.server.impl.StackImpl; import org.jdiameter.server.impl.helpers.XMLConfiguration; import org.mobicents.diameter.dictionary.AvpDictionary; import org.mobicents.diameter.dictionary.AvpRepresentation; /** * @author baranowb */ public class ExampleServer implements NetworkReqListener { private static final Logger log = Logger.getLogger(ExampleServer.class); static { configLog4j(); } private static void configLog4j() { InputStream inStreamLog4j = ExampleServer.class.getClassLoader().getResourceAsStream("log4j.properties"); Properties propertiesLog4j = new Properties(); try { propertiesLog4j.load(inStreamLog4j); PropertyConfigurator.configure(propertiesLog4j); } catch (Exception e) { e.printStackTrace(); } log.debug("log4j configured"); } private static final String configFile = "org/example/server/server-jdiameter-config.xml"; private static final String dictionaryFile = "org/example/client/dictionary.xml"; private static final String realmName = "exchange.example.org"; // Defs for our app private static final int commandCode = 686; private static final long vendorID = 66666; private static final long applicationID = 33333; private ApplicationId authAppId = ApplicationId.createByAuthAppId(applicationID); ; private static final int exchangeTypeCode = 888; private static final int exchangeDataCode = 999; // enum values for Exchange-Type AVP private static final int EXCHANGE_TYPE_INITIAL = 0; private static final int EXCHANGE_TYPE_INTERMEDIATE = 1; private static final int EXCHANGE_TYPE_TERMINATING = 2; private static final String[] TO_RECEIVE = new String[]{"I want to get 3 answers", "This is second message", "Bye bye"}; private AvpDictionary dictionary = AvpDictionary.INSTANCE; private Stack stack; private SessionFactory factory; // //////////////////////////////////////// // Objects which will be used in action // // //////////////////////////////////////// private Session session; private int toReceiveIndex = 0; private boolean finished = false; private void initStack() { if (log.isInfoEnabled()) { log.info("Initializing Stack..."); } InputStream is = null; try { dictionary.parseDictionary(this.getClass().getClassLoader().getResourceAsStream(dictionaryFile)); log.info("AVP Dictionary successfully parsed."); this.stack = new StackImpl(); is = this.getClass().getClassLoader().getResourceAsStream(configFile); Configuration config = new XMLConfiguration(is); factory = stack.init(config); if (log.isInfoEnabled()) { log.info("Stack Configuration successfully loaded."); } Set appIds = stack.getMetaData().getLocalPeer().getCommonApplications(); log.info("Diameter Stack :: Supporting " + appIds.size() + " applications."); for (org.jdiameter.api.ApplicationId x : appIds) { log.info("Diameter Stack :: Common :: " + x); } is.close(); Network network = stack.unwrap(Network.class); network.addNetworkReqListener(this, this.authAppId); } catch (Exception e) { e.printStackTrace(); if (this.stack != null) { this.stack.destroy(); } if (is != null) { try { is.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } return; } MetaData metaData = stack.getMetaData(); if (metaData.getStackType() != StackType.TYPE_SERVER || metaData.getMinorVersion() <= 0) { stack.destroy(); if (log.isEnabledFor(org.apache.log4j.Level.ERROR)) { log.error("Incorrect driver"); } return; } try { if (log.isInfoEnabled()) { log.info("Starting stack"); } stack.start(); if (log.isInfoEnabled()) { log.info("Stack is running."); } } catch (Exception e) { e.printStackTrace(); stack.destroy(); return; } if (log.isInfoEnabled()) { log.info("Stack initialization successfully completed."); } } private void dumpMessage(Message message, boolean sending) { if (log.isInfoEnabled()) { log.info((sending ? "Sending " : "Received ") + (message.isRequest() ? "Request: " : "Answer: ") + message.getCommandCode() + "\nE2E:" + message.getEndToEndIdentifier() + "\nHBH:" + message.getHopByHopIdentifier() + "\nAppID:" + message.getApplicationId()); log.info("AVPS[" + message.getAvps().size() + "]: \n"); try { printAvps(message.getAvps()); } catch (AvpDataException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private void printAvps(AvpSet avpSet) throws AvpDataException { printAvpsAux(avpSet, 0); } /** * Prints the AVPs present in an AvpSet with a specified 'tab' level * * @param avpSet the AvpSet containing the AVPs to be printed * @param level an int representing the number of 'tabs' to make a pretty * print * @throws AvpDataException */ private void printAvpsAux(AvpSet avpSet, int level) throws AvpDataException { String prefix = " ".substring(0, level * 2); for (Avp avp : avpSet) { AvpRepresentation avpRep = AvpDictionary.INSTANCE.getAvp(avp.getCode(), avp.getVendorId()); if (avpRep != null && avpRep.getType().equals("Grouped")) { log.info(prefix + ""); printAvpsAux(avp.getGrouped(), level + 1); log.info(prefix + ""); } else if (avpRep != null) { String value = ""; if (avpRep.getType().equals("Integer32")) value = String.valueOf(avp.getInteger32()); else if (avpRep.getType().equals("Integer64") || avpRep.getType().equals("Unsigned64")) value = String.valueOf(avp.getInteger64()); else if (avpRep.getType().equals("Unsigned32")) value = String.valueOf(avp.getUnsigned32()); else if (avpRep.getType().equals("Float32")) value = String.valueOf(avp.getFloat32()); else //value = avp.getOctetString(); value = new String(avp.getOctetString(), StandardCharsets.UTF_8); log.info(prefix + ""); } } } /** * @return */ private boolean finished() { return this.finished; } public static void main(String[] args) { ExampleServer es = new ExampleServer(); es.initStack(); while (!es.finished()) { try { Thread.currentThread().sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /* * (non-Javadoc) * * @see * org.jdiameter.api.NetworkReqListener#processRequest(org.jdiameter.api * .Request) */ @Override public Answer processRequest(Request request) { dumpMessage(request, false); if (request.getCommandCode() != commandCode) { log.error("Received bad answer: " + request.getCommandCode()); return null; } AvpSet requestAvpSet = request.getAvps(); Avp exchangeTypeAvp = requestAvpSet.getAvp(exchangeTypeCode, vendorID); Avp exchangeDataAvp = requestAvpSet.getAvp(exchangeDataCode, vendorID); if (exchangeTypeAvp == null) { log.error("Request does not have Exchange-Type"); Answer answer = createAnswer(request, 5004, EXCHANGE_TYPE_TERMINATING); dumpMessage(answer, true); return answer; // set // exchange // type // to // terminating } if (exchangeDataAvp == null) { log.error("Request does not have Exchange-Data"); Answer answer = createAnswer(request, 5004, EXCHANGE_TYPE_TERMINATING); dumpMessage(answer, true); return answer; // set // exchange // type // to // terminating } // cast back to int(Enumerated is Unsigned32, and API represents it as // long so its easier // to manipulate try { switch ((int) exchangeTypeAvp.getUnsigned32()) { case EXCHANGE_TYPE_INITIAL: // JIC check; String data = exchangeDataAvp.getUTF8String(); this.session = this.factory.getNewSession(request.getSessionId()); if (data.equals(TO_RECEIVE[toReceiveIndex])) { // create session; Answer answer = createAnswer(request, 2001, EXCHANGE_TYPE_INITIAL); // set // exchange // type // to // terminating toReceiveIndex++; dumpMessage(answer, true); return answer; } else { log.error("Received wrong Exchange-Data: " + data); Answer answer = request.createAnswer(6000); } break; case EXCHANGE_TYPE_INTERMEDIATE: // JIC check; data = exchangeDataAvp.getUTF8String(); if (data.equals(TO_RECEIVE[toReceiveIndex])) { Answer answer = createAnswer(request, 2001, EXCHANGE_TYPE_INTERMEDIATE); // set // exchange // type // to // terminating toReceiveIndex++; dumpMessage(answer, true); return answer; } else { log.error("Received wrong Exchange-Data: " + data); } break; case EXCHANGE_TYPE_TERMINATING: data = exchangeDataAvp.getUTF8String(); if (data.equals(TO_RECEIVE[toReceiveIndex])) { // good, we reached end of FSM. finished = true; // release session and its resources. Answer answer = createAnswer(request, 2001, EXCHANGE_TYPE_TERMINATING); // set // exchange // type // to // terminating toReceiveIndex++; this.session.release(); finished = true; this.session = null; dumpMessage(answer, true); return answer; } else { log.error("Received wrong Exchange-Data: " + data); } break; default: log.error("Bad value of Exchange-Type avp: " + exchangeTypeAvp.getUnsigned32()); break; } } catch (AvpDataException e) { // thrown when interpretation of byte[] fails e.printStackTrace(); } catch (InternalException e) { // TODO Auto-generated catch block e.printStackTrace(); } //error, something bad happened. finished = true; return null; } private Answer createAnswer(Request r, int resultCode, int enumType) { Answer answer = r.createAnswer(resultCode); AvpSet answerAvps = answer.getAvps(); // code , value , vendor, mandatory,protected,isUnsigned32 // (Enumerated) Avp exchangeType = answerAvps.addAvp(exchangeTypeCode, (long) enumType, vendorID, true, false, true); // value // is // set // on // creation // code , value , vendor, mandatory,protected, isOctetString Avp exchengeData = answerAvps.addAvp(exchangeDataCode, TO_RECEIVE[toReceiveIndex], vendorID, true, false, false); // value // is // set // on // creation //add origin, its required by duplicate detection answerAvps.addAvp(Avp.ORIGIN_HOST, stack.getMetaData().getLocalPeer().getUri().getFQDN(), true, false, true); answerAvps.addAvp(Avp.ORIGIN_REALM, stack.getMetaData().getLocalPeer().getRealmName(), true, false, true); return answer; } } ================================================ FILE: examples/guide1/src/main/resources/log4j.properties ================================================ # Set root logger level to DEBUG and its only appender to A1. log4j.rootLogger=DEBUG, A1 # A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.ConsoleAppender # File #log4j.appender.R=org.apache.log4j.RollingFileAppender #log4j.appender.R.File=log4j.log #log4j.appender.R.File=/home/abhayani/workarea/mobicents/svn/trunk/servers/media/test-suite/core/target/mylogfile.log # Archive log files (one backup file here) #log4j.appender.R.MaxBackupIndex=1 #log4j.appender.R.layout=org.apache.log4j.PatternLayout #log4j.appender.R.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n log4j.logger.org.mobicents.tests.diameter=INFO log4j.logger.org.jdiameter=DEBUG log4j.logger.jdiameter=OFF log4j.logger.org.jdiameter.common.impl.validation=OFF ================================================ FILE: examples/guide1/src/main/resources/org/example/client/client-jdiameter-config.xml ================================================ ================================================ FILE: examples/guide1/src/main/resources/org/example/client/dictionary.xml ================================================ /> ================================================ FILE: examples/guide1/src/main/resources/org/example/server/dictionary.xml ================================================ /> ================================================ FILE: examples/guide1/src/main/resources/org/example/server/server-jdiameter-config.xml ================================================ ================================================ FILE: integration-tests/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter quarkus-jdiameter-parent 2.5.1-SNAPSHOT quarkus-jdiameter-integration-tests Quarkus :: JDiameter Integration Tests :: Tests true io.quarkus quarkus-rest ${quarkus.version} io.quarkiverse.jdiameter quarkus-jdiameter ${project.version} io.quarkus quarkus-junit5 ${quarkus.version} test io.rest-assured rest-assured 6.0.0 test io.quarkus quarkus-maven-plugin ${quarkus.version} true build maven-failsafe-plugin integration-test verify ${project.build.directory}/${project.build.finalName}-runner org.jboss.logmanager.LogManager ${maven.home} ================================================ FILE: integration-tests/src/main/java/io/quarkiverse/jdiameter/it/JdiameterResource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 io.quarkiverse.jdiameter.it; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; @Path("/jdiameter") @ApplicationScoped public class JdiameterResource { // add some rest methods here @GET public String hello() { return "Hello jdiameter"; } } ================================================ FILE: integration-tests/src/main/resources/application.properties ================================================ ================================================ FILE: integration-tests/src/test/java/io/quarkiverse/jdiameter/it/JdiameterResourceIT.java ================================================ package io.quarkiverse.jdiameter.it; import io.quarkus.test.junit.QuarkusIntegrationTest; @QuarkusIntegrationTest public class JdiameterResourceIT extends JdiameterResourceTest { } ================================================ FILE: integration-tests/src/test/java/io/quarkiverse/jdiameter/it/JdiameterResourceTest.java ================================================ package io.quarkiverse.jdiameter.it; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.is; import org.junit.jupiter.api.Test; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest public class JdiameterResourceTest { @Test public void testHelloEndpoint() { given() .when().get("/jdiameter") .then() .statusCode(200) .body(is("Hello jdiameter")); } } ================================================ FILE: lombok.config ================================================ lombok.log.fieldName=LOG ================================================ FILE: pom.xml ================================================ io.quarkiverse quarkiverse-parent 21 4.0.0 io.quarkiverse.jdiameter quarkus-jdiameter-parent 2.5.1-SNAPSHOT pom Quarkus :: JDiameter :: ${project.artifactId} Quarkus JDiameter Parent scm:git:git@github.com:quarkiverse/quarkus-jdiameter.git scm:git:git@github.com:quarkiverse/quarkus-jdiameter.git https://github.com/quarkiverse/quarkus-jdiameter HEAD GitHub https://github.com/eddiecarpenter/quarkus-jdiameter/issues/ GNU Affero General Public License https://www.gnu.org/licenses/agpl-3.0.html repo eddiecarpenter Eddie Carpenter eddie.carpenter@icloud.com Project Lead NZST (GMT+12) core quarkus-diameter true UTF-8 true 1.6 6.0.3 2.0.17 4.2.12.Final 4.0.1 3.5.5 3.1.2 1.18.44 21 21 21 3.15.0 21 3.2.5 3.6.2 3.5.3 UTF-8 UTF-8 3.34.4 3.5.0 ${maven.compiler.source} ERROR central Maven Repository Switchboard https://repo.maven.apache.org/maven2 false io.quarkus quarkus-bom ${quarkus.version} pom import org.projectlombok lombok ${lombok.version} io.quarkiverse.jdiameter quarkus-jdiameter ${project.version} io.quarkiverse.jdiameter jdiameter-api ${project.version} io.quarkiverse.jdiameter jdiameter-impl ${project.version} org.apache.maven.plugins maven-enforcer-plugin ${maven.enforcer.version} enforce-java-version enforce To build this project, don't use maven repositories over HTTP. Please use HTTPS in your settings.xml or run the build with property insecure.repositories=WARN ${insecure.repositories} http://* http://* To build this project JDK ${jdk.min.version} (or greater) is required. Please install it. ${jdk.min.version} enforce-maven-version enforce To build this project Maven ${maven.min.version} (or greater) is required. Please install it. ${maven.min.version} maven-compiler-plugin ${compiler-plugin.version} true org.apache.maven.plugins maven-surefire-plugin ${surefire.version} true docs performRelease !true docs it performRelease !true integration-tests ================================================ FILE: quarkus-diameter/deployment/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter quarkus-jdiameter-extension-parent 2.5.1-SNAPSHOT ../pom.xml quarkus-jdiameter-deployment Quarkus :: JDiameter Extension :: Deployment io.quarkus quarkus-arc-deployment io.quarkus quarkus-junit5-internal test io.quarkiverse.jdiameter quarkus-jdiameter io.quarkus quarkus-tls-registry-deployment maven-compiler-plugin io.quarkus quarkus-extension-processor ${quarkus.version} ================================================ FILE: quarkus-diameter/deployment/src/main/java/io/quarkiverse/diameter/deployment/DiameterBuildItem.java ================================================ package io.quarkiverse.diameter.deployment; import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.runtime.RuntimeValue; import org.jdiameter.api.Configuration; import org.jdiameter.api.Stack; public final class DiameterBuildItem extends MultiBuildItem { private final RuntimeValue configuration; private final RuntimeValue stack; private final String name; public DiameterBuildItem(String name, RuntimeValue stack, RuntimeValue configuration) { this.stack = stack; this.configuration = configuration; this.name = name; } public RuntimeValue getStack() { return stack; } public RuntimeValue getConfiguration() { return configuration; } public String getName() { return name; } } ================================================ FILE: quarkus-diameter/deployment/src/main/java/io/quarkiverse/diameter/deployment/DiameterProcessor.java ================================================ package io.quarkiverse.diameter.deployment; import io.quarkiverse.diameter.DiameterConfig; import io.quarkiverse.diameter.DiameterService; import io.quarkiverse.diameter.runtime.DiameterRecorder; import io.quarkiverse.diameter.runtime.JDiameterVersionRecorder; import io.quarkus.arc.deployment.AdditionalBeanBuildItem; import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.processor.DotNames; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.deployment.builditem.ServiceStartBuildItem; import io.quarkus.deployment.builditem.ShutdownContextBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.Startup; import io.quarkus.tls.deployment.spi.TlsRegistryBuildItem; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Default; import jakarta.interceptor.Interceptor; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTransformation; import org.jboss.jandex.DotName; import org.jdiameter.api.Configuration; import org.jdiameter.api.Stack; import org.jdiameter.client.impl.SessionFactoryImpl; import org.jdiameter.client.impl.controller.RealmTableImpl; import org.jdiameter.client.impl.helpers.AssemblerImpl; import org.jdiameter.client.impl.parser.MessageParser; import org.jdiameter.client.impl.router.WeightedLeastConnectionsRouter; import org.jdiameter.client.impl.router.WeightedRoundRobinRouter; import org.jdiameter.client.impl.transport.tcp.TCPClientConnection; import org.jdiameter.common.impl.concurrent.ConcurrentEntityFactory; import org.jdiameter.common.impl.concurrent.ConcurrentFactory; import org.jdiameter.common.impl.data.LocalDataSource; import org.jdiameter.common.impl.statistic.StatisticManagerImpl; import org.jdiameter.common.impl.statistic.StatisticProcessorImpl; import org.jdiameter.common.impl.timer.LocalTimerFacilityImpl; import org.jdiameter.common.impl.validation.DictionaryImpl; import org.jdiameter.impl.ha.data.CachedSessionDatasourceImpl; import org.jdiameter.impl.ha.timer.ReplicatedTimerFacilityImpl; import org.jdiameter.server.impl.*; import org.jdiameter.server.impl.agent.AgentConfigurationImpl; import org.jdiameter.server.impl.agent.ProxyAgentImpl; import org.jdiameter.server.impl.agent.RedirectAgentImpl; import org.jdiameter.server.impl.fsm.FsmFactoryImpl; import org.jdiameter.server.impl.io.TransportLayerFactory; import org.jdiameter.server.impl.io.tcp.NetworkGuard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashSet; import java.util.List; import java.util.Set; import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT; class DiameterProcessor { private static final Logger LOG = LoggerFactory.getLogger(DiameterProcessor.class); private static final String FEATURE = "diameter"; private static final DotName DOTNAME_CONFIGURATION = DotName.createSimple("org.jdiameter.api.Configuration"); private static final DotName DOTNAME_STACK = DotName.createSimple("org.jdiameter.api.Stack"); private static final DotName DOTNAME_DIAMETER_SERVICE = DotName.createSimple("io.quarkiverse.diameter.DiameterService"); private static final DotName DOTNAME_DIAMETER_SERVICE_OPTIONS = DotName.createSimple("io.quarkiverse.diameter.DiameterServiceOptions"); private static final DotName DOTNAME_DIAMETER_CONFIG = DotName.createSimple("io.quarkiverse.diameter.DiameterConfig"); private static final DotName DOTNAME_DIAMETER_SERVICE_INTERCEPTOR = DotName.createSimple("io.quarkiverse.diameter.DiameterServiceInterceptor"); @BuildStep public FeatureBuildItem feature() { return new FeatureBuildItem(FEATURE); } @Record(RUNTIME_INIT) @BuildStep void logVersion(JDiameterVersionRecorder recorder) { recorder.logVersion(); } @BuildStep NativeImageResourceBuildItem nativeImageResourceBuildItem() { return new NativeImageResourceBuildItem("META-INF/jdiameter-client.xsd", "META-INF/jdiameter-server.xsd", "META-INF/version.properties", "dictionary.xml"); } @BuildStep ReflectiveClassBuildItem reflection() { return ReflectiveClassBuildItem.builder(ConcurrentEntityFactory.class, DictionaryImpl.class, StatisticProcessorImpl.class, ConcurrentFactory.class, LocalTimerFacilityImpl.class, LocalDataSource.class, ProxyAgentImpl.class, AgentConfigurationImpl.class, RedirectAgentImpl.class, MutablePeerTableImpl.class, RealmTableImpl.class, StatisticManagerImpl.class, SessionFactoryImpl.class, NetworkGuard.class, TCPClientConnection.class, OverloadManagerImpl.class, NetworkImpl.class, RouterImpl.class, org.jdiameter.client.impl.router.RouterImpl.class, FsmFactoryImpl.class, org.jdiameter.client.impl.fsm.FsmFactoryImpl.class, TransportLayerFactory.class, org.jdiameter.client.impl.transport.TransportLayerFactory.class, MetaDataImpl.class, org.jdiameter.client.impl.MetaDataImpl.class, AssemblerImpl.class, MessageParser.class, WeightedRoundRobinRouter.class, WeightedLeastConnectionsRouter.class, CachedSessionDatasourceImpl.class, ReplicatedTimerFacilityImpl.class ) .methods() .fields() .constructors() .build(); } @Record(RUNTIME_INIT) @BuildStep public void discoverInjectedClients(DiameterRecorder recorder, CombinedIndexBuildItem index, TlsRegistryBuildItem tlsRegistryBuildItem, ShutdownContextBuildItem shutdownContextBuildItem, BuildProducer diameterStacks) { Set profileNames = new HashSet<>(); for (AnnotationInstance annotation : index.getIndex().getAnnotations(DOTNAME_DIAMETER_CONFIG)) { if (annotation.value() == null) { profileNames.add(DiameterConfig.DEFAULT_CONFIG_NAME); } else { profileNames.add((String) annotation.value().value()); } } for (AnnotationInstance annotation : index.getIndex().getAnnotations(DOTNAME_DIAMETER_SERVICE_OPTIONS)) { if (annotation.value() == null) { profileNames.add(DiameterConfig.DEFAULT_CONFIG_NAME); } else { profileNames.add((String) annotation.value().value()); } } for (AnnotationInstance annotation : index.getIndex().getAnnotations(DOTNAME_DIAMETER_SERVICE)) { if (!annotation.target().asClass().name().equals(DOTNAME_DIAMETER_SERVICE_INTERCEPTOR) && annotation.target().annotation(DOTNAME_DIAMETER_SERVICE_OPTIONS) == null) { profileNames.add(DiameterConfig.DEFAULT_CONFIG_NAME); } } profileNames.forEach(n -> { RuntimeValue configuration = recorder.loadDiameterConfiguration(tlsRegistryBuildItem.registry(), n); RuntimeValue stack = recorder.loadDiameterStack(shutdownContextBuildItem, configuration, n); diameterStacks.produce(new DiameterBuildItem(n, stack, configuration)); }); } @BuildStep public ServiceStartBuildItem generateDiameterConfiguration(List stacks, BuildProducer syntheticBeanBuildItemBuildProducer) { stacks.forEach(stack -> { syntheticBeanBuildItemBuildProducer.produce( createSyntheticBean(stack.getName(), Configuration.class, DOTNAME_CONFIGURATION, stack.getName().equals(DiameterConfig.DEFAULT_CONFIG_NAME)) .runtimeValue(stack.getConfiguration()) .done()); syntheticBeanBuildItemBuildProducer.produce( createSyntheticBean(stack.getName(), Stack.class, DOTNAME_STACK, stack.getName().equals(DiameterConfig.DEFAULT_CONFIG_NAME)) .runtimeValue(stack.getStack()) .done()); //Handle the case where the default name is explicitly injected. if (stack.getName().equals(DiameterConfig.DEFAULT_CONFIG_NAME)) { syntheticBeanBuildItemBuildProducer.produce( createSyntheticBean(stack.getName(), Configuration.class, DOTNAME_CONFIGURATION, false) .runtimeValue(stack.getConfiguration()) .done()); syntheticBeanBuildItemBuildProducer.produce( createSyntheticBean(stack.getName(), Stack.class, DOTNAME_STACK, false) .runtimeValue(stack.getStack()) .done()); } }); return new ServiceStartBuildItem("DiameterService"); } @BuildStep public void declareDiameterServicesAsBean(CombinedIndexBuildItem index, BuildProducer additionalBeans, BuildProducer transformer) { List diameterServices = index.getIndex() .getKnownClasses() .stream() .filter(ci -> ci.hasAnnotation(DiameterService.class) && !ci.hasAnnotation(Interceptor.class)) .map(ci -> ci.name().toString()) .toList(); additionalBeans.produce(new AdditionalBeanBuildItem.Builder() .addBeanClasses(diameterServices) .setUnremovable() .setDefaultScope(DotNames.SINGLETON) .build()); transformer.produce(new AnnotationsTransformerBuildItem(AnnotationTransformation.forClasses() .whenClass(c -> diameterServices.contains(c.name().toString())) .transform(c -> c.add(AnnotationInstance.builder(Startup.class).build())))); } private static SyntheticBeanBuildItem.ExtendedBeanConfigurator createSyntheticBean(String clientName, Class type, DotName exposedType, boolean isDefaultConfig) { LOG.info("Creating Synthetic Bean to {} for @DiameterClient(\"{}\")", type.getSimpleName(), clientName); SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator = SyntheticBeanBuildItem .configure(type) .scope(ApplicationScoped.class) .unremovable() .setRuntimeInit() .addType(exposedType); if (isDefaultConfig) { configurator.defaultBean(); configurator.addQualifier(Default.class) .addQualifier(DiameterConfig.class); } else { configurator.addQualifier() .annotation(DiameterConfig.class) .addValue("value", clientName).done(); } return configurator; } } ================================================ FILE: quarkus-diameter/deployment/src/test/java/io/quarkiverse/diameter/deployment/DiameterConfigTest.java ================================================ package io.quarkiverse.diameter.deployment; import io.quarkiverse.diameter.DiameterConfig; import io.quarkus.test.QuarkusUnitTest; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jdiameter.api.Configuration; import org.jdiameter.server.impl.helpers.Parameters; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; public class DiameterConfigTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)).withConfigurationResource("application.properties"); @DiameterConfig Configuration defaultConfiguration; @DiameterConfig("test1") Configuration test1Configuration; @Test public void testConfig() { assertNotNull(defaultConfiguration); assertEquals("aaa://ocsclient:1812", defaultConfiguration.getStringValue(Parameters.OwnDiameterURI.ordinal(), null)); assertNotNull(test1Configuration); assertEquals("aaa://ocsclient:1813", test1Configuration.getStringValue(Parameters.OwnDiameterURI.ordinal(), null)); } } ================================================ FILE: quarkus-diameter/deployment/src/test/java/io/quarkiverse/diameter/deployment/DiameterInterceptorTest.java ================================================ package io.quarkiverse.diameter.deployment; import io.quarkiverse.diameter.DiameterService; import io.quarkiverse.diameter.DiameterServiceOptions; import io.quarkus.test.QuarkusUnitTest; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.api.RouteException; import org.jdiameter.api.cca.ClientCCASession; import org.jdiameter.api.cca.ClientCCASessionListener; import org.jdiameter.api.cca.events.JCreditControlAnswer; import org.jdiameter.api.cca.events.JCreditControlRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; public class DiameterInterceptorTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(DiameterServiceTest.class)).withConfigurationResource("application.properties"); @Test public void testInterceptor() { //Dummy test to trigger the test case } @DiameterServiceOptions @DiameterService static class DiameterServiceTest implements ClientCCASessionListener { @Override public void doCreditControlAnswer(ClientCCASession session, JCreditControlRequest request, JCreditControlAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { } } } ================================================ FILE: quarkus-diameter/deployment/src/test/java/io/quarkiverse/diameter/deployment/DiameterStackTest.java ================================================ package io.quarkiverse.diameter.deployment; import io.quarkiverse.diameter.DiameterConfig; import io.quarkus.test.QuarkusUnitTest; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jdiameter.api.Stack; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; public class DiameterStackTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest().setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)).withConfigurationResource("application.properties"); @DiameterConfig Stack defaultStack; @DiameterConfig("test1") Stack test1Stack; @Test public void testConfig() { assertNotNull(defaultStack); assertEquals("aaa://ocsclient:1812", defaultStack.getMetaData().getLocalPeer().getUri().toString()); assertNotNull(test1Stack); assertEquals("aaa://ocsclient:1813", test1Stack.getMetaData().getLocalPeer().getUri().toString()); } } ================================================ FILE: quarkus-diameter/deployment/src/test/java/io/quarkiverse/diameter/deployment/DiameterValidatorTest.java ================================================ package io.quarkiverse.diameter.deployment; import io.quarkiverse.diameter.DiameterService; import io.quarkiverse.diameter.runtime.DiameterSetupException; import io.quarkus.test.QuarkusUnitTest; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; public class DiameterValidatorTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest().setExpectedException(DiameterSetupException.class).setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(TestClass.class)).withConfigurationResource("application.properties"); @Test public void testValidation() { //Dummy test to trigger the test case } @DiameterService static class TestClass { } } ================================================ FILE: quarkus-diameter/deployment/src/test/resources/application.properties ================================================ diameter.local-peer.uri=aaa://ocsclient:1812 diameter.local-peer.ip-addresses[0]=0.0.0.0 diameter.local-peer.ip-addresses[1]=127.0.0.1 diameter.local-peer.realm=server.test.com diameter.local-peer.product-name=Diameter Test Client diameter.local-peer.firmware-revision=1 diameter.local-peer.applications[0].auth-appl-id=4 diameter.local-peer.applications[1].auth-appl-id=4 diameter.local-peer.applications[1].vendor-id=10415 diameter.parameter.use-virtual-threads=true diameter.network.peers[0].peer-uri=aaa://ocs.test.org:3868 diameter.network.peers[0].ip=127.0.0.1 diameter.network.peers[0].attempt-connect=true diameter.network.peers[0].rating=0 diameter.network.realms[0].realm-name=server.test.com diameter.network.realms[0].peers=192.168.241.1,localhost diameter.network.realms[0].local-action=local diameter.network.realms[0].dynamic=false diameter.network.realms[0].exp-time=1 diameter.network.realms[0].application-id.auth-appl-id=4 diameter.test1.local-peer.uri=aaa://ocsclient:1813 diameter.test1.local-peer.ip-addresses[0]=0.0.0.0 diameter.test1.local-peer.ip-addresses[1]=127.0.0.1 diameter.test1.local-peer.realm=server.test.com diameter.test1.local-peer.product-name=Diameter Test Client diameter.test1.local-peer.firmware-revision=1 diameter.test1.local-peer.applications[0].auth-appl-id=4 diameter.test1.local-peer.applications[1].auth-appl-id=4 diameter.test1.local-peer.applications[1].vendor-id=10415 diameter.test1.parameter.use-virtual-threads=false diameter.test1.network.peers[0].peer-uri=aaa://ocs.test.org:3868 diameter.test1.network.peers[0].ip=127.0.0.1 diameter.test1.network.peers[0].attempt-connect=true diameter.test1.network.peers[0].rating=0 diameter.test1.network.realms[0].realm-name=server.test.com diameter.test1.network.realms[0].peers=192.168.241.1,localhost diameter.test1.network.realms[0].local-action=local diameter.test1.network.realms[0].dynamic=false diameter.test1.network.realms[0].exp-time=1 diameter.test1.network.realms[0].application-id.auth-appl-id=4 ================================================ FILE: quarkus-diameter/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter quarkus-jdiameter-parent 2.5.1-SNAPSHOT ../pom.xml quarkus-jdiameter-extension-parent pom Quarkus :: JDiameter Extension :: Parent deployment runtime io.quarkiverse.jdiameter jdiameter-api ${project.version} io.quarkiverse.jdiameter jdiameter-impl ${project.version} io.quarkiverse.jdiameter jdiameter-ha-api ${project.version} io.quarkiverse.jdiameter jdiameter-ha-impl ${project.version} io.quarkus quarkus-maven-plugin ${quarkus.version} maven-surefire-plugin ${surefire-plugin.version} org.jboss.logmanager.LogManager ${maven.home} ${settings.localRepository} maven-failsafe-plugin ${failsafe-plugin.version} org.jboss.logmanager.LogManager ${maven.home} ${settings.localRepository} maven-compiler-plugin ${compiler-plugin.version} -parameters ================================================ FILE: quarkus-diameter/runtime/pom.xml ================================================ 4.0.0 io.quarkiverse.jdiameter quarkus-jdiameter-extension-parent 2.5.1-SNAPSHOT ../pom.xml quarkus-jdiameter Quarkus :: JDiameter Extension :: Runtime true io.quarkus quarkus-arc io.quarkus quarkus-tls-registry org.projectlombok lombok io.quarkiverse.jdiameter jdiameter-api io.quarkiverse.jdiameter jdiameter-impl io.quarkiverse.jdiameter jdiameter-ha-impl io.quarkus quarkus-extension-maven-plugin ${quarkus.version} compile extension-descriptor ${project.groupId}:${project.artifactId}-deployment:${project.version} io.quarkiverse.jdiameter maven-compiler-plugin io.quarkus quarkus-extension-processor ${quarkus.version} io.smallrye jandex-maven-plugin ${maven-jandex-plugin.version} make-index jandex ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/ApplicationMode.java ================================================ package io.quarkiverse.diameter; public enum ApplicationMode { CLIENT, SERVER } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/DiameterApplication.java ================================================ package io.quarkiverse.diameter; public enum DiameterApplication { CCA, RX, S6A, GQ } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/DiameterConfig.java ================================================ package io.quarkiverse.diameter; import jakarta.enterprise.util.AnnotationLiteral; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.Objects; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({TYPE, FIELD, METHOD, PARAMETER, PACKAGE}) @Retention(RUNTIME) @Documented @Qualifier public @interface DiameterConfig { String DEFAULT_CONFIG_NAME = ""; String value() default DEFAULT_CONFIG_NAME; @SuppressWarnings("ClassExplicitlyAnnotation") final class DiameterConfigLiteral extends AnnotationLiteral implements DiameterConfig { private final String name; public DiameterConfigLiteral(String name) { this.name = name; } @Override public String value() { return name; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof DiameterConfigLiteral that)) return false; if (!super.equals(o)) return false; return Objects.equals(name, that.name); } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (name != null ? name.hashCode() : 0); return result; } } } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/DiameterService.java ================================================ package io.quarkiverse.diameter; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({TYPE}) @Retention(RUNTIME) @Documented @InterceptorBinding public @interface DiameterService { } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/DiameterServiceInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 io.quarkiverse.diameter; import io.quarkus.arc.Arc; import io.quarkus.arc.InstanceHandle; import jakarta.annotation.PostConstruct; import jakarta.annotation.Priority; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import org.jdiameter.api.*; import org.jdiameter.api.acc.ClientAccSession; import org.jdiameter.api.acc.ClientAccSessionListener; import org.jdiameter.api.acc.ServerAccSession; import org.jdiameter.api.acc.ServerAccSessionListener; import org.jdiameter.api.app.AppSession; import org.jdiameter.api.auth.ClientAuthSession; import org.jdiameter.api.auth.ClientAuthSessionListener; import org.jdiameter.api.auth.ServerAuthSession; import org.jdiameter.api.auth.ServerAuthSessionListener; import org.jdiameter.api.cca.ClientCCASession; import org.jdiameter.api.cca.ClientCCASessionListener; import org.jdiameter.api.cca.ServerCCASession; import org.jdiameter.api.cca.ServerCCASessionListener; import org.jdiameter.api.cxdx.ClientCxDxSession; import org.jdiameter.api.cxdx.ClientCxDxSessionListener; import org.jdiameter.api.cxdx.ServerCxDxSession; import org.jdiameter.api.cxdx.ServerCxDxSessionListener; import org.jdiameter.api.gq.ClientGqSessionListener; import org.jdiameter.api.gq.ServerGqSessionListener; import org.jdiameter.api.gx.ClientGxSession; import org.jdiameter.api.gx.ClientGxSessionListener; import org.jdiameter.api.gx.ServerGxSession; import org.jdiameter.api.gx.ServerGxSessionListener; import org.jdiameter.api.rf.ClientRfSession; import org.jdiameter.api.rf.ClientRfSessionListener; import org.jdiameter.api.rf.ServerRfSession; import org.jdiameter.api.rf.ServerRfSessionListener; import org.jdiameter.api.ro.ClientRoSession; import org.jdiameter.api.ro.ClientRoSessionListener; import org.jdiameter.api.ro.ServerRoSession; import org.jdiameter.api.ro.ServerRoSessionListener; import org.jdiameter.api.rx.ClientRxSession; import org.jdiameter.api.rx.ClientRxSessionListener; import org.jdiameter.api.rx.ServerRxSession; import org.jdiameter.api.rx.ServerRxSessionListener; import org.jdiameter.api.s13.ClientS13Session; import org.jdiameter.api.s13.ClientS13SessionListener; import org.jdiameter.api.s13.ServerS13Session; import org.jdiameter.api.s13.ServerS13SessionListener; import org.jdiameter.api.s6a.ClientS6aSession; import org.jdiameter.api.s6a.ClientS6aSessionListener; import org.jdiameter.api.s6a.ServerS6aSession; import org.jdiameter.api.s6a.ServerS6aSessionListener; import org.jdiameter.api.sh.ClientShSession; import org.jdiameter.api.sh.ClientShSessionListener; import org.jdiameter.api.sh.ServerShSession; import org.jdiameter.api.sh.ServerShSessionListener; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.impl.app.acc.AccSessionFactoryImpl; import org.jdiameter.common.impl.app.auth.AuthSessionFactoryImpl; import org.jdiameter.common.impl.app.cca.CCASessionFactoryImpl; import org.jdiameter.common.impl.app.cxdx.CxDxSessionFactoryImpl; import org.jdiameter.common.impl.app.gq.GqSessionFactoryImpl; import org.jdiameter.common.impl.app.gx.GxSessionFactoryImpl; import org.jdiameter.common.impl.app.rf.RfSessionFactoryImpl; import org.jdiameter.common.impl.app.ro.RoSessionFactoryImpl; import org.jdiameter.common.impl.app.rx.RxSessionFactoryImpl; import org.jdiameter.common.impl.app.s13.S13SessionFactoryImpl; import org.jdiameter.common.impl.app.s6a.S6aSessionFactoryImpl; import org.jdiameter.common.impl.app.sh.ShSessionFactoryImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.Set; @DiameterService @Interceptor @Priority(Interceptor.Priority.APPLICATION) public class DiameterServiceInterceptor { private static final Logger LOG = LoggerFactory.getLogger(DiameterServiceInterceptor.class); private void setupClientCAAFactory(ISessionFactory sessionFactory, String configProfile, ClientCCASessionListener sessionListener) { LOG.info("Staring CAA Diameter Client Service [{}].", configProfile); CCASessionFactoryImpl sessionFactoryImpl = new CCASessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientCCASession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(sessionListener); } private void setupServerCAAFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerCCASessionListener sessionListener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring CAA Diameter Server Service [{}].", configProfile); CCASessionFactoryImpl sessionFactoryImpl = new CCASessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerCCASession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(sessionListener); setupDiameterServer(stack, sessionFactory, ServerCCASession.class, sessionListener, configProfile); } private void setupClientGxFactory(ISessionFactory sessionFactory, String configProfile, ClientGxSessionListener sessionListener) { LOG.info("Staring Gx Diameter Client Service [{}].", configProfile); GxSessionFactoryImpl sessionFactoryImpl = new GxSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientGxSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(sessionListener); } private void setupServerGxFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerGxSessionListener sessionListener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring Gx Diameter Server Service [{}].", configProfile); GxSessionFactoryImpl sessionFactoryImpl = new GxSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerGxSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(sessionListener); setupDiameterServer(stack, sessionFactory, ServerGxSession.class, sessionListener, configProfile); } private void clientSetupRxFactory(ISessionFactory sessionFactory, String configProfile, ClientRxSessionListener listener) { LOG.info("Staring Rx Diameter Client Service [{}].", configProfile); RxSessionFactoryImpl sessionFactoryImpl = new RxSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientRxSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(listener); } private void serverSetupRxFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerRxSessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring Rx Diameter Server Service [{}].", configProfile); RxSessionFactoryImpl sessionFactoryImpl = new RxSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerRxSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerRxSession.class, listener, configProfile); } private void clientSetupS6aFactory(ISessionFactory sessionFactory, String configProfile, ClientS6aSessionListener listener) { LOG.info("Staring S6a Diameter Client Service [{}].", configProfile); S6aSessionFactoryImpl sessionFactoryImpl = new S6aSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientS6aSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(listener); } private void serverSetupS6aFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerS6aSessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring S6a Diameter Server Service [{}].", configProfile); S6aSessionFactoryImpl sessionFactoryImpl = new S6aSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerS6aSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerS6aSession.class, listener, configProfile); } private void clientSetupGqFactory(ISessionFactory sessionFactory, String configProfile, ClientGqSessionListener listener) { LOG.info("Staring Gq Diameter Client Service [{}].", configProfile); GqSessionFactoryImpl sessionFactoryImpl = new GqSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientAuthSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(listener); } private void serverSetupGqFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerGqSessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring Gq Diameter Server Service [{}].", configProfile); GqSessionFactoryImpl sessionFactoryImpl = new GqSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerAuthSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerAuthSession.class, listener, configProfile); } private void clientSetupShFactory(ISessionFactory sessionFactory, String configProfile, ClientShSessionListener listener) { LOG.info("Staring Sh Diameter Client Service [{}].", configProfile); ShSessionFactoryImpl sessionFactoryImpl = new ShSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientShSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientShSessionListener(listener); } private void serverSetupShFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerShSessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring Sh Diameter Server Service [{}].", configProfile); ShSessionFactoryImpl sessionFactoryImpl = new ShSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerShSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerShSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerShSession.class, listener, configProfile); } private void clientSetupCxDxFactory(ISessionFactory sessionFactory, String configProfile, ClientCxDxSessionListener listener) { LOG.info("Staring CxDx Diameter Client Service [{}].", configProfile); CxDxSessionFactoryImpl sessionFactoryImpl = new CxDxSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientCxDxSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(listener); } private void serverSetupCxDxFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerCxDxSessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring CxDx Diameter Server Service [{}].", configProfile); CxDxSessionFactoryImpl sessionFactoryImpl = new CxDxSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerCxDxSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerShSession.class, listener, configProfile); } private void clientSetupS13Factory(ISessionFactory sessionFactory, String configProfile, ClientS13SessionListener listener) { LOG.info("Staring S13 Diameter Client Service [{}].", configProfile); S13SessionFactoryImpl sessionFactoryImpl = new S13SessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientS13Session.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(listener); } private void serverSetupS13Factory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerS13SessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring S13 Diameter Server Service [{}].", configProfile); S13SessionFactoryImpl sessionFactoryImpl = new S13SessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerS13Session.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerS13Session.class, listener, configProfile); } private void clientSetupRoFactory(ISessionFactory sessionFactory, String configProfile, ClientRoSessionListener listener) { LOG.info("Staring Ro Diameter Client Service [{}].", configProfile); RoSessionFactoryImpl sessionFactoryImpl = new RoSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientRoSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(listener); } private void serverSetupRoFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerRoSessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring Ro Diameter Server Service [{}].", configProfile); RoSessionFactoryImpl sessionFactoryImpl = new RoSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerRoSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerRoSession.class, listener, configProfile); } private void clientSetupRfFactory(ISessionFactory sessionFactory, String configProfile, ClientRfSessionListener listener) { LOG.info("Staring Rf Diameter Client Service [{}].", configProfile); RfSessionFactoryImpl sessionFactoryImpl = new RfSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientRfSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(listener); } private void serverSetupRfFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerRfSessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring Rf Diameter Server Service [{}].", configProfile); RfSessionFactoryImpl sessionFactoryImpl = new RfSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerRfSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerRfSession.class, listener, configProfile); } private void clientSetupAuthFactory(ISessionFactory sessionFactory, String configProfile, ClientAuthSessionListener listener) { LOG.info("Staring Auth Diameter Client Service [{}].", configProfile); AuthSessionFactoryImpl sessionFactoryImpl = new AuthSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientAuthSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(listener); } private void serverSetupAuthFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerAuthSessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring Auth Diameter Server Service [{}].", configProfile); AuthSessionFactoryImpl sessionFactoryImpl = new AuthSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerAuthSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerAuthSession.class, listener, configProfile); } private void clientSetupAccFactory(ISessionFactory sessionFactory, String configProfile, ClientAccSessionListener listener) { LOG.info("Staring Acc Diameter Client Service [{}].", configProfile); AccSessionFactoryImpl sessionFactoryImpl = new AccSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ClientAccSession.class, sessionFactoryImpl); sessionFactoryImpl.setClientSessionListener(listener); } private void serverSetupAccFactory(Stack stack, ISessionFactory sessionFactory, String configProfile, ServerAccSessionListener listener) throws ApplicationAlreadyUseException, InternalException { LOG.info("Staring Auth Diameter Server Service [{}].", configProfile); AccSessionFactoryImpl sessionFactoryImpl = new AccSessionFactoryImpl(sessionFactory); sessionFactory.registerAppFacory(ServerAccSession.class, sessionFactoryImpl); sessionFactoryImpl.setServerSessionListener(listener); setupDiameterServer(stack, sessionFactory, ServerAccSession.class, listener, configProfile); } private NetworkReqListener createListener(ISessionFactory sessionFactory, Class appSession) { return request -> { try { ApplicationId appId = request.getApplicationIdAvps().isEmpty() ? null : request.getApplicationIdAvps().getFirst(); LOG.debug("Received request for {} and {}", appSession.getSimpleName(), appId); NetworkReqListener listener = sessionFactory.getNewAppSession(request.getSessionId(), appId, appSession, Collections.emptyList()); return listener.processRequest(request); } catch (InternalException e) { LOG.error(">< Failure handling received request.", e); } return null; }; } private void setupDiameterServer(Stack stack, ISessionFactory sessionFactory, Class appSessionClass, Object target, String configProfile) throws ApplicationAlreadyUseException, InternalException { NetworkReqListener networkReqListener; //Check if the target implements their own listener. If they do, use their listener if ((target instanceof NetworkReqListener listener)) { networkReqListener = listener; } else { networkReqListener = createListener(sessionFactory, appSessionClass); } Network network = stack.unwrap(Network.class); Set applIds = stack.getMetaData().getLocalPeer().getCommonApplications(); if (!applIds.isEmpty()) { LOG.info("Diameter Server [{}]: Registering {} configured application(s)", configProfile, applIds.size()); for (ApplicationId applId : applIds) { LOG.debug("Diameter Server [{}]: Registering {}", configProfile, applId); network.addNetworkReqListener(networkReqListener, applId); } } } @PostConstruct public Object startStack(InvocationContext context) throws Exception { String configProfile; DiameterServiceOptions options = context.getTarget().getClass().getAnnotation(DiameterServiceOptions.class); if (options == null) { configProfile = DiameterConfig.DEFAULT_CONFIG_NAME; } else { configProfile = options.value(); } try (InstanceHandle stackHandle = Arc.container().instance(Stack.class, new DiameterConfig.DiameterConfigLiteral(configProfile))) { if (stackHandle.isAvailable()) { Stack stack = stackHandle.get(); ISessionFactory sessionFactory = (ISessionFactory) stack.getSessionFactory(); if (context.getTarget() instanceof ClientCCASessionListener listener) { setupClientCAAFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerCCASessionListener listener) { setupServerCAAFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientGxSessionListener listener) { setupClientGxFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerGxSessionListener listener) { setupServerGxFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientRxSessionListener listener) { clientSetupRxFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerRxSessionListener listener) { serverSetupRxFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientS6aSessionListener listener) { clientSetupS6aFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerS6aSessionListener listener) { serverSetupS6aFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientGqSessionListener listener) { clientSetupGqFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerGqSessionListener listener) { serverSetupGqFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientShSessionListener listener) { clientSetupShFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerShSessionListener listener) { serverSetupShFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientCxDxSessionListener listener) { clientSetupCxDxFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerCxDxSessionListener listener) { serverSetupCxDxFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientS13SessionListener listener) { clientSetupS13Factory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerS13SessionListener listener) { serverSetupS13Factory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientRoSessionListener listener) { clientSetupRoFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerRoSessionListener listener) { serverSetupRoFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientRfSessionListener listener) { clientSetupRfFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerRfSessionListener listener) { serverSetupRfFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientAuthSessionListener listener) { clientSetupAuthFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerAuthSessionListener listener) { serverSetupAuthFactory(stack, sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ClientAccSessionListener listener) { clientSetupAccFactory(sessionFactory, configProfile, listener); } if (context.getTarget() instanceof ServerAccSessionListener listener) { serverSetupAccFactory(stack, sessionFactory, configProfile, listener); } if (!stack.isActive()) { LOG.debug("Starting the Diameter Stack [{}].", configProfile); if (options != null && options.timeOut() > 0) { stack.start(Mode.ALL_PEERS, options.timeOut(), options.timeUnit()); } else { stack.start(); } } else { LOG.debug("The Diameter Stack is already started [{}].", configProfile); } } } return context.proceed(); } } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/DiameterServiceOptions.java ================================================ package io.quarkiverse.diameter; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.concurrent.TimeUnit; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({TYPE}) @Retention(RUNTIME) @Documented public @interface DiameterServiceOptions { /** * Specifies the diameter configuration name */ String value() default DiameterConfig.DEFAULT_CONFIG_NAME; /** * If > 0 wait for the peers to start */ long timeOut() default 0; TimeUnit timeUnit() default TimeUnit.MILLISECONDS; } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/DiameterConfiguration.java ================================================ package io.quarkiverse.diameter.runtime; import io.quarkiverse.diameter.runtime.config.*; import io.quarkiverse.diameter.runtime.transport.TLSClientConnection; import io.quarkus.tls.TlsConfiguration; import io.quarkus.tls.TlsConfigurationRegistry; import org.jdiameter.api.Configuration; import org.jdiameter.client.impl.helpers.AppConfiguration; import org.jdiameter.client.impl.helpers.Ordinal; import org.jdiameter.server.impl.helpers.EmptyConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; import static org.jdiameter.server.impl.helpers.ExtensionPoint.*; import static org.jdiameter.server.impl.helpers.Parameters.*; public class DiameterConfiguration extends EmptyConfiguration { private static final Logger LOG = LoggerFactory.getLogger(DiameterConfiguration.class); private final TlsConfigurationRegistry tlsRegistry; private final List securityItems; public DiameterConfiguration(DiameterDetailConfig config, TlsConfigurationRegistry tlsRegistry) { super(true); securityItems = new ArrayList<>(); this.tlsRegistry = tlsRegistry; addLocalPeer(config.localPeer()); addParameters(config.parameter()); addNetwork(config.network()); if (config.extensions() != null) { addExtensions(config.extensions()); } if (!securityItems.isEmpty()) { addInternalExtension(InternalTransportFactory, TLSClientConnection.class.getCanonicalName()); add(Security, securityItems.toArray(EMPTY_ARRAY)); }//if } protected void addLocalPeer(LocalPeer peerConfig) { LOG.warn("Adding local peer '{}'.", peerConfig.uri()); add(OwnDiameterURI, peerConfig.uri()); add(OwnRealm, peerConfig.realm()); add(OwnVendorID, peerConfig.vendorId()); add(OwnProductName, peerConfig.productName()); add(OwnFirmwareRevision, peerConfig.firmwareRevision()); if (!peerConfig.applications().isEmpty()) { addApplications(peerConfig.applications().values()); } addIPAddresses(peerConfig.ipAddresses()); if (!peerConfig.overloadMonitors().isEmpty()) { addOverloadMonitor(peerConfig.overloadMonitors().values()); } if (peerConfig.tlsConfigurationName().isPresent()) { TlsConfiguration tlsConfig = tlsRegistry.get(peerConfig.tlsConfigurationName().get()).orElse(null); if (tlsConfig == null) { throw new DiameterSetupException("Tls configuration '" + peerConfig.tlsConfigurationName().get() + "' not found"); } add(SecurityRef, peerConfig.tlsConfigurationName().get()); securityItems.add(getInstance().add(SDName, peerConfig.tlsConfigurationName().get()).add(SecurityData, tlsConfig)); } } protected void addOverloadMonitor(Collection entries) { ArrayList items = new ArrayList<>(); entries.forEach(entry -> items.add(addOverloadMonitorItem(entry))); add(OverloadMonitor, items.toArray(EMPTY_ARRAY)); } protected Configuration addOverloadMonitorItem(OverloadMonitor entry) { return EmptyConfiguration.getInstance().add(OverloadEntryIndex, entry.index()).add(OverloadEntrylowThreshold, entry.lowThreshold()).add(OverloadEntryhighThreshold, entry.highThreshold()).add(ApplicationId, addApplicationID(entry.applicationId())); } protected void addIPAddresses(Set ipAddresses) { ArrayList items = new ArrayList<>(); ipAddresses.forEach(ip -> items.add(EmptyConfiguration.getInstance().add(OwnIPAddress, ip.trim()))); add(OwnIPAddresses, items.toArray(EMPTY_ARRAY)); } protected Configuration addApplicationID(io.quarkiverse.diameter.runtime.config.ApplicationId applicationId) { return EmptyConfiguration.getInstance() .add(VendorId, applicationId.vendorId()) .add(AuthApplId, applicationId.authApplId()) .add(AcctApplId, applicationId.acctApplId()); } protected void addApplications(Collection applications) { ArrayList items = new ArrayList<>(); for (ApplicationId appId : applications) { items.add(addApplicationID(appId)); } add(ApplicationId, items.toArray(EMPTY_ARRAY)); } protected void addParameters(Parameter parametersConfig) { add(AcceptUndefinedPeer, parametersConfig.acceptUndefinedPeer()); add(DuplicateProtection, parametersConfig.duplicateProtection()); add(UseUriAsFqdn, parametersConfig.useUriAsFqdn()); add(DuplicateTimer, parametersConfig.duplicateTimer()); add(DuplicateSize, parametersConfig.duplicateSize()); add(UseVirtualThreads, parametersConfig.useVirtualThreads()); add(CachingName, parametersConfig.cachingName()); if (parametersConfig.queueSize().isPresent()) { add(QueueSize, parametersConfig.queueSize().get()); } if (parametersConfig.messageTimeout().isPresent()) { add(MessageTimeOut, parametersConfig.messageTimeout().get()); } if (parametersConfig.stopTimeout().isPresent()) { add(StopTimeOut, parametersConfig.stopTimeout().get()); } if (parametersConfig.ceaTimeout().isPresent()) { add(CeaTimeOut, parametersConfig.ceaTimeout().get()); } if (parametersConfig.iacTimeout().isPresent()) { add(IacTimeOut, parametersConfig.iacTimeout().get()); } if (parametersConfig.dwaTimeout().isPresent()) { add(DwaTimeOut, parametersConfig.dwaTimeout().get()); } if (parametersConfig.dpaTimeout().isPresent()) { add(DpaTimeOut, parametersConfig.dpaTimeout().get()); } if (parametersConfig.recTimeout().isPresent()) { add(RecTimeOut, parametersConfig.recTimeout().get()); } if (parametersConfig.peerFSMThreadCount().isPresent()) { add(PeerFSMThreadCount, parametersConfig.peerFSMThreadCount().get()); } if (parametersConfig.sessionTimeout().isPresent()) { add(SessionTimeOut, parametersConfig.sessionTimeout().get()); } if (parametersConfig.bindDelay().isPresent()) { add(BindDelay, parametersConfig.bindDelay().get()); } if (parametersConfig.concurrent().isPresent()) { addConcurrent(parametersConfig.concurrent().get()); } } protected void addConcurrent(io.quarkiverse.diameter.runtime.config.Concurrent concurrent) { List items = new ArrayList<>(); if (concurrent.applicationSession().isPresent()) { items.add(createConcurrentItem("ApplicationSession", concurrent.applicationSession().get())); } if (concurrent.duplicationMessageTimer().isPresent()) { items.add(createConcurrentItem("DuplicateMessageTimer", concurrent.duplicationMessageTimer().get())); } if (concurrent.processingMessageTimer().isPresent()) { items.add(createConcurrentItem("ProcessingMessageTimer", concurrent.processingMessageTimer().get())); } if (concurrent.connectionTimer().isPresent()) { items.add(createConcurrentItem("ConnectionTimer", concurrent.connectionTimer().get())); } if (concurrent.peerOverloadTimer().isPresent()) { items.add(createConcurrentItem("PeerOverloadTimer", concurrent.peerOverloadTimer().get())); } if (concurrent.redirectMessageTimer().isPresent()) { items.add(createConcurrentItem("RedirectMessageTimer", concurrent.redirectMessageTimer().get())); } if (concurrent.statisticTimer().isPresent()) { items.add(createConcurrentItem("StatisticTimer", concurrent.statisticTimer().get())); } if (concurrent.threadGroup().isPresent()) { items.add(createConcurrentItem("ThreadGroup", concurrent.threadGroup().get())); } add(Concurrent, items.toArray(EMPTY_ARRAY)); } protected AppConfiguration createConcurrentItem(String name, int size) { AppConfiguration cfg = EmptyConfiguration.getInstance(); cfg.add(ConcurrentEntityName, name); cfg.add(ConcurrentEntityPoolSize, size); return cfg; } protected void addNetwork(Network network) { addPeers(network.peers().values()); addRealms(network.realms()); } protected void addPeers(Collection peers) { ArrayList items = new ArrayList<>(); peers.forEach(peer -> items.add(addPeer(peer))); add(PeerTable, items.toArray(EMPTY_ARRAY)); } protected AppConfiguration addPeer(Peer peer) { AppConfiguration peerConfig = EmptyConfiguration.getInstance().add(PeerRating, peer.rating()).add(PeerName, peer.peerUri()).add(PeerAttemptConnection, peer.attemptConnect()); if (peer.ip().isPresent()) { peerConfig.add(PeerIp, peer.ip().get()); } if (peer.portRange().isPresent()) { peerConfig.add(PeerLocalPortRange, peer.portRange().get()); } if (peer.tlsConfigurationName().isPresent()) { TlsConfiguration tlsConfig = tlsRegistry.get(peer.tlsConfigurationName().get()).orElse(null); if (tlsConfig == null) { throw new DiameterSetupException("Tls configuration '" + peer.tlsConfigurationName().get() + "' not found"); } peerConfig.add(SecurityRef, peer.tlsConfigurationName().get()); securityItems.add(getInstance().add(SDName, peer.tlsConfigurationName().get()).add(SecurityData, tlsConfig)); } return peerConfig; } protected void addRealms(Map realms) { ArrayList items = new ArrayList<>(); realms.forEach((name, realm) -> items.add(addRealm(name, realm))); add(RealmTable, items.toArray(EMPTY_ARRAY)); } protected AppConfiguration addAgent(Map properties) { AppConfiguration agentConf = getInstance(); List props = new ArrayList<>(); for (Map.Entry prop : properties.entrySet()) { AppConfiguration property = getInstance(); property.add(PropertyName, prop.getKey()); property.add(PropertyValue, prop.getValue()); props.add(property); } agentConf.add(Properties, props.toArray(EMPTY_ARRAY)); return agentConf; } protected AppConfiguration buildRealm(String name, Realm realm) { AppConfiguration realmEntry = EmptyConfiguration.getInstance() .add(RealmName, name) .add(RealmHosts, realm.peers()) .add(RealmLocalAction, realm.localAction().name()) .add(RealmEntryIsDynamic, realm.dynamic()) .add(RealmEntryExpTime, realm.expTime()); List appIds = new ArrayList<>(); if (realm.applicationId().isPresent()) { for (ApplicationId appId : realm.applicationId().get()) { appIds.add(addApplicationID(appId)); } } realmEntry.add(ApplicationId, appIds.toArray(new Configuration[]{})); if (realm.agent().isPresent()) { realmEntry.add(Agent, addAgent(realm.agent().get().properties())); } return realmEntry; } protected Configuration addRealm(String name, Realm realm) { return EmptyConfiguration.getInstance().add(RealmEntry, buildRealm(name, realm)); } protected void addInternalExtension(Ordinal ep, String value) { Configuration[] extensionConfs = this.getChildren(Extensions.ordinal()); AppConfiguration internalExtensions = (AppConfiguration) extensionConfs[Internal.id()]; internalExtensions.add(ep, value); } protected void addExtensions(Extension extension) { if (extension.metaData().isPresent()) { addInternalExtension(InternalMetaData, extension.metaData().get()); } if (extension.messageParser().isPresent()) { addInternalExtension(InternalMessageParser, extension.messageParser().get()); } if (extension.elementParser().isPresent()) { addInternalExtension(InternalElementParser, extension.elementParser().get()); } if (extension.transportFactory().isPresent()) { addInternalExtension(InternalTransportFactory, extension.transportFactory().get()); } if (extension.connection().isPresent()) { addInternalExtension(InternalConnectionClass, extension.connection().get()); } if (extension.peerFsmFactory().isPresent()) { addInternalExtension(InternalPeerFsmFactory, extension.peerFsmFactory().get()); } if (extension.sessionFactory().isPresent()) { addInternalExtension(InternalSessionFactory, extension.sessionFactory().get()); } if (extension.routerEngine().isPresent()) { addInternalExtension(InternalRouterEngine, extension.routerEngine().get()); } if (extension.statisticFactory().isPresent()) { addInternalExtension(InternalStatisticFactory, extension.statisticFactory().get()); } if (extension.realmController().isPresent()) { addInternalExtension(InternalRealmController, extension.realmController().get()); } if (extension.agentRedirect().isPresent()) { addInternalExtension(InternalAgentRedirect, extension.agentRedirect().get()); } if (extension.agentConfiguration().isPresent()) { addInternalExtension(InternalAgentConfiguration, extension.agentConfiguration().get()); } if (extension.agentProxy().isPresent()) { addInternalExtension(InternalAgentProxy, extension.agentProxy().get()); } if (extension.sessionDatasource().isPresent()) { addInternalExtension(InternalSessionDatasource, extension.sessionDatasource().get()); } if (extension.timerFacility().isPresent()) { addInternalExtension(InternalTimerFacility, extension.timerFacility().get()); } if (extension.peerController().isPresent()) { addInternalExtension(InternalPeerController, extension.peerController().get()); } if (extension.networkGuard().isPresent()) { addInternalExtension(InternalNetworkGuard, extension.networkGuard().get()); } if (extension.network().isPresent()) { addInternalExtension(InternalNetWork, extension.network().get()); } if (extension.overloadManager().isPresent()) { addInternalExtension(InternalOverloadManager, extension.overloadManager().get()); } if (extension.concurrentFactory().isPresent()) { addInternalExtension(InternalConcurrentFactory, extension.concurrentFactory().get()); } if (extension.concurrentEntityFactory().isPresent()) { addInternalExtension(InternalConcurrentEntityFactory, extension.concurrentEntityFactory().get()); } if (extension.statisticProcessor().isPresent()) { addInternalExtension(InternalSessionFactory, extension.statisticProcessor().get()); } } } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/DiameterDetailConfig.java ================================================ package io.quarkiverse.diameter.runtime; import io.quarkiverse.diameter.runtime.config.Extension; import io.quarkiverse.diameter.runtime.config.LocalPeer; import io.quarkiverse.diameter.runtime.config.Network; import io.quarkiverse.diameter.runtime.config.Parameter; import io.quarkus.runtime.annotations.ConfigDocSection; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithDefaults; import io.smallrye.config.WithName; /** * The Diameter Config describes the entire Diameter configuration mapping for both the * server and client */ @ConfigGroup public interface DiameterDetailConfig { /** * The localPeer element contains parameters that affect the local Diameter peer. */ @WithName("local-peer") @WithDefaults @ConfigDocSection LocalPeer localPeer(); /** * The Parameters element contains elements that specify parameters for the Diameter stack. */ @WithName("parameter") @WithDefaults @ConfigDocSection Parameter parameter(); /** * The Network< element contains elements that specify parameters for external peers. */ @WithName("network") @WithDefaults @ConfigDocSection Network network(); /** * The extensions elements contains elements that override existing components in the Diameter stack. */ @WithName("extensions") @ConfigDocSection @WithDefaults Extension extensions(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/DiameterRecorder.java ================================================ package io.quarkiverse.diameter.runtime; import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.ShutdownContext; import io.quarkus.runtime.annotations.Recorder; import io.quarkus.tls.TlsConfigurationRegistry; import org.jdiameter.api.*; import org.jdiameter.common.impl.validation.DictionaryImpl; import org.jdiameter.server.impl.StackImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @Recorder public class DiameterRecorder { private static final Logger LOG = LoggerFactory.getLogger(DiameterRecorder.class); private final RuntimeValue diameterRunTimeConfig; public DiameterRecorder(RuntimeValue diameterRunTimeConfig) { this.diameterRunTimeConfig = diameterRunTimeConfig; } public RuntimeValue loadDiameterConfiguration(Supplier registrySupplier, String configName) { LOG.info("Building Diameter configuration for profile '{}'", configName); DiameterRunTimeConfig runtimeConfig = this.diameterRunTimeConfig.getValue(); DiameterDetailConfig diameterConfig = runtimeConfig.getDiameterConfig(configName); if (diameterConfig == null) { throw new IllegalArgumentException("No Diameter configuration found for profile '" + configName + "'"); } return new RuntimeValue<>(new DiameterConfiguration(diameterConfig, registrySupplier.get())); } public RuntimeValue loadDiameterStack(ShutdownContext shutdownContext, RuntimeValue diameterConfig, String configName) { try { DictionaryImpl.INSTANCE.setEnabled(true); LOG.info("Building Diameter Stack for configuration profile '{}'", configName); Stack stack = new StackImpl(); stack.init(diameterConfig.getValue()); shutdownContext.addShutdownTask(() -> { LOG.info("Stopping '{}' Diameter Stack", configName); if (stack.isActive()) { try { stack.stop(10, TimeUnit.SECONDS, DisconnectCause.REBOOTING); } catch (IllegalDiameterStateException | InternalException ex) { LOG.error("Error stopping Diameter Stack", ex); } stack.destroy(); } }); return new RuntimeValue<>(stack); } catch (IllegalDiameterStateException | InternalException ex) { LOG.error("Error creating '{}' Diameter Stack", configName, ex); throw new DiameterSetupException("Error creating '" + configName + "' Diameter stack"); } } } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/DiameterRunTimeConfig.java ================================================ package io.quarkiverse.diameter.runtime; import io.quarkiverse.diameter.DiameterConfig; import io.quarkus.runtime.annotations.ConfigDocMapKey; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; import io.smallrye.config.ConfigMapping; import io.smallrye.config.WithDefaults; import io.smallrye.config.WithParentName; import io.smallrye.config.WithUnnamedKey; import java.util.Map; @ConfigMapping(prefix = "quarkus.diameter") @ConfigRoot(phase = ConfigPhase.RUN_TIME) public interface DiameterRunTimeConfig { /** * The defined named diameter client config * * @asciidocx */ @WithParentName @WithUnnamedKey(DiameterConfig.DEFAULT_CONFIG_NAME) @ConfigDocMapKey("named-config") @WithDefaults Map diameterConfigs(); default DiameterDetailConfig getDiameterConfig(String clientName) { return diameterConfigs().get(clientName); }//getDiameterConfig } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/DiameterSetupException.java ================================================ package io.quarkiverse.diameter.runtime; public class DiameterSetupException extends RuntimeException { public DiameterSetupException(String message) { super(message); } public DiameterSetupException(String message, Throwable cause) { super(message, cause); } public DiameterSetupException(Throwable cause) { super(cause); } public DiameterSetupException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/JDiameterVersionRecorder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 io.quarkiverse.diameter.runtime; import io.quarkus.runtime.annotations.Recorder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.util.Properties; @Recorder public class JDiameterVersionRecorder { private static final Logger LOG = LoggerFactory.getLogger(JDiameterVersionRecorder.class); public static final String DEFAULT_VERSION = "0.0.0-DEFAULT_VERSION"; public static final String QUARKUS_JDIAMETER_POM_PROPERTIES = "/META-INF/maven/io.quarkiverse.jdiameter/quarkus-jdiameter/pom.properties"; public void logVersion() { // Read from pom.properties with native fallback String version = resolveVersion(); LOG.info("Quarkus Jdiameter extension loaded — version: {}", version); } private String resolveVersion() { // Try pom.properties first (JVM mode) try (InputStream is = getClass().getResourceAsStream(QUARKUS_JDIAMETER_POM_PROPERTIES)) { if (is != null) { Properties p = new Properties(); p.load(is); return p.getProperty("version", DEFAULT_VERSION); } } catch (IOException ignored) {} // Fallback: MANIFEST.MF Implementation-Version String manifestVersion = getClass().getPackage().getImplementationVersion(); if (manifestVersion != null) return manifestVersion; return DEFAULT_VERSION; } } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/Agent.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithParentName; import java.util.Map; @ConfigGroup public interface Agent { /** * Retrieves the properties of the agent configuration. */ @WithParentName Map properties(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/ApplicationId.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithDefault; import io.smallrye.config.WithName; @ConfigGroup public interface ApplicationId { /** * Specifies the vendor ID for application definition. */ @WithDefault("0") @WithName("vendor-id") Long vendorId(); /** * The Authentication Application ID for application definition. */ @WithDefault("0") @WithName("auth-appl-id") Long authApplId(); /** * The Account Application ID for application definition. */ @WithDefault("0") @WithName("acct-appl-id") Long acctApplId(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/Concurrent.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithName; import java.util.Optional; @ConfigGroup public interface Concurrent { /** * Determines the maximum thread count in other entities. */ @WithName("thread-group") Optional threadGroup(); /** * Determines the thread count for message processing tasks. */ @WithName("processing-message-timer") Optional processingMessageTimer(); /** * Specifies the thread pool for identifying duplicate messages. */ @WithName("duplication-message-timer") Optional duplicationMessageTimer(); /** * Specifies the thread pool for redirecting messages that do not need any further processing. */ @WithName("redirect-message-timer") Optional redirectMessageTimer(); /** * Determines the thread pool for managing the overload monitor. */ @WithName("peer-overload-timer") Optional peerOverloadTimer(); /** * Determines the thread pool for managing tasks regarding peer connection FSM. */ @WithName("connection-timer") Optional connectionTimer(); /** * Determines the thread pool for statistic gathering tasks. */ @WithName("statistic-timer") Optional statisticTimer(); /** * Determines the thread pool for managing the invocation of application session FSMs, * which will invoke listeners. */ @WithName("application-session") Optional applicationSession(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/Extension.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithName; import java.util.Optional; @ConfigGroup public interface Extension { /** * The MetaData extension */ @WithName("metadata") Optional metaData(); /** * The MetaData extension */ @WithName("message-parser") Optional messageParser(); /** * The MetaData extension */ @WithName("element-parser") Optional elementParser(); /** * The MetaData extension */ @WithName("router-engine") Optional routerEngine(); /** * The MetaData extension */ @WithName("peer-controller") Optional peerController(); /** * The Realm Controller extension */ @WithName("realm-controller") Optional realmController(); /** * The Session Factory extension */ @WithName("session-factory") Optional sessionFactory(); /** * The Transport Factory extension */ @WithName("transport-factory") Optional transportFactory(); /** * The Connection extension */ @WithName("connection") Optional connection(); /** * The Network Guard extension */ @WithName("network-guard") Optional networkGuard(); /** * The Peer Fsm Factory extension */ @WithName("peer-fsm-factory") Optional peerFsmFactory(); /** * The Statistic Factory extension */ @WithName("statistic-factory") Optional statisticFactory(); /** * The Concurrent Factory extension */ @WithName("concurrent-factory") Optional concurrentFactory(); /** * The Concurrent Entity Factory extension */ @WithName("concurrent-entity-factory") Optional concurrentEntityFactory(); /** * The Statistic Processor extension */ @WithName("statistic-processor") Optional statisticProcessor(); /** * The Network extension */ @WithName("network") Optional network(); /** * The Session Datasource extension */ @WithName("session-datasource") Optional sessionDatasource(); /** * The Timer Facility extension */ @WithName("timer-facility") Optional timerFacility(); /** * The Agent Redirect extension */ @WithName("agent-redirect") Optional agentRedirect(); /** * The Agent Configuration extension */ @WithName("agent-configuration") Optional agentConfiguration(); /** * The Agent Proxy extension */ @WithName("agent-proxy") Optional agentProxy(); /** * The Overload Manager extension */ @WithName("overload-manager") Optional overloadManager(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/LocalPeer.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigDocSection; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithDefault; import io.smallrye.config.WithName; import io.smallrye.config.WithUnnamedKey; import java.util.Map; import java.util.Optional; import java.util.Set; @ConfigGroup public interface LocalPeer { /** * Specifies the URI for the local peer. The URI has the following format: "aaa://FQDN:port". */ @WithDefault("aaa://localhost:1812") @WithName("uri") String uri(); /** * The name of the TLS configuration to use. *

      * If not set and the default TLS configuration is configured ({@code quarkus.tls.*}) then that will be used. * If a name is configured, it uses the configuration from {@code quarkus.tls..*} * If a name is configured, but no TLS configuration is found with that name then an error will be thrown. *

      * If no TLS configuration is set, and {@code quarkus.tls.*} is not configured, then, no security will be used */ @WithName("tls-configuration-name") Optional tlsConfigurationName(); /** * Contains one or more valid IP address for the local peer.` */ @WithName("ip-addresses") @WithDefault("127.0.0.1") Set ipAddresses(); /** * Specifies the realm of the local peer. */ @WithName("realm") @WithDefault("io.quarkiverse.diameter") String realm(); /** * Specifies the name of the local peer product */ @WithDefault("Go Diameter") @WithName("product-name") String productName(); /** * Specifies the version of the firmware. */ @WithDefault("3") @WithName("firmware-revision") long firmwareRevision(); /** * Specifies a numeric identifier that corresponds to the vendor ID allocated by IANA. */ @WithDefault("0") @WithName("vendor-id") long vendorId(); /** * Contains a list of default supported applications. */ @WithName("applications") @ConfigDocSection @WithUnnamedKey Map applications(); /** * Optional parent element containing child elements that specify settings * relating to the Overload Monitor. The map key is the index of this overload monitor, * so priorities/orders can be specified. */ @WithName("overload-monitors") @ConfigDocSection Map overloadMonitors(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/Network.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigDocSection; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithName; import java.util.Map; /** * The Network element contains elements that specify parameters for external peers. * The available elements and attributes are listed for reference. */ @ConfigGroup public interface Network { /** * List of external peers and the way they connect. */ @WithName("peers") @ConfigDocSection Map peers(); /** * List of all realms that connect into the Diameter network. */ @WithName("realms") @ConfigDocSection Map realms(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/OverloadMonitor.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithName; @ConfigGroup /* * The Overload Monitor configuration */ public interface OverloadMonitor { /** * Defines the index of this overload monitor, so priorities/orders can be specified. */ @WithName("index") int index(); /** * The low threshold for activation of the overload monitor. */ @WithName("low-threshold") double lowThreshold(); /** * The high threshold for activation of the overload monitor. */ @WithName("high-threshold") double highThreshold(); /** * The application that is overloaded */ @WithName("application-id") ApplicationId applicationId(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/Parameter.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithDefault; import io.smallrye.config.WithName; import java.util.Optional; @ConfigGroup public interface Parameter { /** * Specifies whether the stack will accept connections from undefined peers. * The default value is `false` */ @WithDefault("false") @WithName("accept-undefined-peer") Boolean acceptUndefinedPeer(); /** * Specifies whether duplicate message protection is enabled. * The default value is `false`. */ @WithDefault("false") @WithName("duplicate-protection") Boolean duplicateProtection(); /** * Determines whether the URI should be used as FQDN. * If it is set to `true`, the stack expects the destination/origin host to be in the * format of "aaa://isdn.domain.com:3868" rather than the normal "isdn.domain.com". * The default value is `false`. */ @WithDefault("false") @WithName("use-uri-as-fqdn") Boolean useUriAsFqdn(); /** * Specifies whether the stack should use virtual threads * The default value is `false` */ @WithDefault("false") @WithName("use-virtual-threads") Boolean useVirtualThreads(); /** * Specifies the time each duplicate message is valid for (in extreme cases, it can * live up to 2 * DuplicateTimer - 1 milliseconds). * The default, minimum value is `240000` (4 minutes in milliseconds). */ @WithDefault("240000") @WithName("duplicate-timer") Long duplicateTimer(); /** * Specifies the number of requests stored for duplicate protection. * The default value is `5000`. */ @WithDefault("5000") @WithName("duplicate-size") Integer duplicateSize(); /** * Determines how many tasks the peer state machine can have before rejecting the next task. * This queue contains FSM events and messaging */ @WithName("queue-size") Optional queueSize(); /** * Determines the timeout for messages other than protocol FSM messages. * The delay is in milliseconds. */ @WithName("message-timeout") Optional messageTimeout(); /** * Determines how long the stack waits for all resources to stop. * The delays are in milliseconds. */ @WithName("stop-timeout") Optional stopTimeout(); /** * Determines how long it takes for CER/CEA exchanges to timeout if there is no response. * The delays are in milliseconds. */ @WithName("cea-timeout") Optional ceaTimeout(); /** * Determines how long the stack waits to retry the communication with a peer that * has stopped answering DWR messages. * The delay is in milliseconds. */ @WithName("iac-timeout") Optional iacTimeout(); /** * Determines how long it takes for a DWR/DWA exchange to timeout if there is no response. * The delay is in milliseconds. */ @WithName("dwa-timeout") Optional dwaTimeout(); /** * Determines how long it takes for a DPR/DPA exchange to timeout if there is no response. * The delay is in milliseconds. */ @WithName("dpa-timeout") Optional dpaTimeout(); /** * Determines how long it takes for the reconnection procedure to timeout. * The delay is in milliseconds. */ @WithName("rec-timeout") Optional recTimeout(); /** * Determines how long it takes for the session to timeout * The delay is in milliseconds. */ @WithName("session-Timeout") Optional sessionTimeout(); /** * Determines the number of threads for handling events in the Peer FSM. */ @WithName("peer-fsm-thread-count") Optional peerFSMThreadCount(); /** * Determines a delay before binding. * The delay is in milliseconds. */ @WithName("bind-delay") Optional bindDelay(); /** * Controls the thread pool sizes for different aspects of the stack. */ @WithName("concurrent") Optional concurrent(); /** * The caching name to be used if HA datasource is used */ @WithDefault("diameter") @WithName("caching-name") String cachingName(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/Peer.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithDefault; import io.smallrye.config.WithName; import java.util.Optional; /** * Parent element containing the child Peer elements */ @ConfigGroup public interface Peer { /** * Specifies the name of the peer in the form of a URI. * The structure is "aaa://[fqdn|ip]:port" (for example, "aaa://192.168.1.1:3868"). */ @WithDefault("aaa://localhost:3868") @WithName("peer-uri") String peerUri(); /** * Specifies the rating of this peer in order to achieve peer priorities/sorting. */ @WithDefault("1") @WithName("rating") int rating(); /** * Specifies the actual ip for the peer-uri, for example 192.168.1.1 */ @WithName("ip") Optional ip(); /** * Specifies a port range to accept connection override the port number in peer-uri */ @WithName("port-range") Optional portRange(); /** * Determines if the stack should try to connect to this peer. */ @WithDefault("false") @WithName("attempt-connect") Boolean attemptConnect(); /** * The name of the TLS configuration to use. *

      * If not set and the default TLS configuration is configured ({@code quarkus.tls.*}) then that will be used. * If a name is configured, it uses the configuration from {@code quarkus.tls..*} * If a name is configured, but no TLS configuration is found with that name then an error will be thrown. *

      * If no TLS configuration is set, and {@code quarkus.tls.*} is not configured, then, no security will be used */ @WithName("tls-configuration-name") Optional tlsConfigurationName(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/config/Realm.java ================================================ package io.quarkiverse.diameter.runtime.config; import io.quarkus.runtime.annotations.ConfigGroup; import io.smallrye.config.WithDefault; import io.smallrye.config.WithName; import org.jdiameter.api.LocalAction; import java.util.List; import java.util.Optional; /** * Parent element containing all realms that connect into the Diameter network. */ @ConfigGroup public interface Realm { /** * Comma separated list of peers. Each peer is represented by an IP Address or FQDN. */ @WithName("peers") @WithDefault("localhost") String peers(); /** * Determines the action the Local Peer will play on the specified realm: Act as a LOCAL peer. */ @WithDefault("LOCAL") @WithName("local-action") LocalAction localAction(); /** * Specifies if this realm is dynamic. That is, peers that * connect to peers with this realm name will be added to the realm peer * list if not present already. */ @WithDefault("false") @WithName("dynamic") Boolean dynamic(); /** * The time before a peer belonging to this realm is removed if no connection is available. * The time is in seconds. */ @WithDefault("1") @WithName("exp-time") long expTime(); /** * The applications supported. */ @WithName("application-id") Optional> applicationId(); /** * The Agent configuration */ @WithName("agent") Optional agent(); } ================================================ FILE: quarkus-diameter/runtime/src/main/java/io/quarkiverse/diameter/runtime/transport/TLSClientConnection.java ================================================ package io.quarkiverse.diameter.runtime.transport; import io.quarkus.tls.TlsConfiguration; import org.jdiameter.api.Configuration; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.common.api.concurrent.IConcurrentFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import java.net.InetAddress; import java.net.Socket; import static org.jdiameter.client.impl.helpers.Parameters.SecurityData; public class TLSClientConnection extends org.jdiameter.client.impl.transport.tls.TLSClientConnection { public TLSClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IMessageParser parser, String ref) { super(config, concurrentFactory, remoteAddress, remotePort, localAddress, localPort, parser, ref); } public TLSClientConnection(Configuration config, IConcurrentFactory concurrentFactory, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IConnectionListener listener, IMessageParser parser, String ref) { super(config, concurrentFactory, remoteAddress, remotePort, localAddress, localPort, listener, parser, ref); } public TLSClientConnection(Configuration config, Configuration localPeerSSLConfig, IConcurrentFactory concurrentFactory, Socket socket, IMessageParser parser) throws Exception { super(config, localPeerSSLConfig, concurrentFactory, socket, parser); } @Override protected SSLSocketFactory fillSecurityData(Configuration sslConfig) throws Exception { Object secData = sslConfig.getValue(SecurityData.ordinal()); if (secData instanceof TlsConfiguration tlsConfiguration) { SSLContext context = tlsConfiguration.createSSLContext(); return context.getSocketFactory(); } return super.fillSecurityData(sslConfig); } @Override protected SSLSocketFactory fillSecurityData(Configuration config, String ref) throws Exception { Object secData = config.getValue(SecurityData.ordinal()); if (secData instanceof TlsConfiguration tlsConfiguration) { SSLContext context = tlsConfiguration.createSSLContext(); return context.getSocketFactory(); } return super.fillSecurityData(config, ref); } } ================================================ FILE: quarkus-diameter/runtime/src/main/resources/META-INF/quarkus-extension.yaml ================================================ name: Quarkus JDiameter description: Quarkus Diameter Extension metadata: config: - "quarkus.diameter." # guide: https://quarkiverse.github.io/quarkiverse-docs/jdiameter/dev/ # To create and publish this guide, see https://github.com/quarkiverse/quarkiverse/wiki#documenting-your-extension # categories: # - "miscellaneous" # status: "preview"