├── .gitignore ├── .gitmodules ├── .travis.yml ├── LICENSE.txt ├── NOTICE.txt ├── README.md ├── TESTS.md ├── bin ├── keycloak-setup.sh └── ups-setup.sh ├── common ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── jboss │ │ └── aerogear │ │ └── unifiedpush │ │ └── system │ │ ├── ConfigurationEnvironment.java │ │ └── ConfigurationUtils.java │ └── test │ ├── java │ └── org │ │ └── jboss │ │ └── aerogear │ │ └── unifiedpush │ │ └── system │ │ └── ConfigurationUtilsTest.java │ └── resources │ └── logback.xml ├── databases ├── docker-compose │ ├── mysql-database-config-wildfly.cli │ ├── ups-datasource.yml │ └── ups-galera-cluster.yml ├── h2-database-config-wildfly.cli ├── ha_deployment │ ├── deploy-managed-domain.cli │ ├── mysql-database-config-wildfly-full-ha.cli │ └── mysql-database-config-wildfly-managed-domain.cli ├── initdb │ ├── assembly.xml │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ └── DBMaintenance.java │ │ └── resources │ │ ├── META-INF │ │ ├── db.properties │ │ └── hibernate.properties │ │ └── bin │ │ ├── cassandra-keyspace.cql │ │ ├── cassandra-tables.cql │ │ ├── init-cassandra-db.sh │ │ ├── init-unifiedpush-db.bat │ │ └── init-unifiedpush-db.sh ├── migration │ ├── README.md │ ├── keycloak-migration-mysql.sql │ ├── keycloak-migration-postgresql.sql │ ├── ups-migration-mysql.sql │ └── ups-migration-postgresql.sql ├── mysql-database-config-wildfly.cli ├── postgresql-database-config-wildfly.cli ├── prepare_clean_wf11.sh ├── src │ └── main │ │ └── resources │ │ └── modules │ │ ├── com │ │ └── mysql │ │ │ └── jdbc │ │ │ └── main │ │ │ └── module.xml │ │ └── org │ │ └── postgresql │ │ └── main │ │ └── module.xml └── unifiedpush-h2-ds.xml ├── dependencies ├── pom.xml └── server-dependencies │ └── pom.xml ├── dist ├── README.md ├── pom.xml └── src │ └── main │ └── assembly │ └── assembly.xml ├── docker-compose ├── development │ ├── README.md │ ├── development-env.yaml │ └── ups-realm │ │ └── ups-realm-sample.json └── ups-master │ ├── .env │ ├── README.md │ ├── docker-compose-v1.yaml │ └── docker-compose-v3x.yaml ├── integration-tests ├── pom.xml └── src │ └── test │ ├── jmeter │ ├── enable-android-installation-fregment.jmx │ ├── enable-ios-installation-fregment.jmx │ ├── register-android-installation-fregment.jmx │ ├── register-applications-fail-on-error.jmx │ ├── register-applications.jmx │ ├── register-installations-and-documents.jmx │ ├── register-ios-installation-fregment.jmx │ ├── register-params-installations-fail-on-error.jmx │ ├── register-params-installations-fregment.jmx │ ├── register-params-installations.jmx │ ├── register-random-installations-and-applications.jmx │ ├── register-random-installations-fregment.jmx │ └── register-random-installations.jmx │ └── resources │ └── development.p12 ├── jaxrs ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ └── rest │ │ │ ├── AbstractBaseEndpoint.java │ │ │ ├── AbstractEndpoint.java │ │ │ ├── AbstractManagementEndpoint.java │ │ │ ├── EmptyJSON.java │ │ │ ├── HeartbeatEndpoint.java │ │ │ ├── PasswordContainer.java │ │ │ ├── RestApplication.java │ │ │ ├── SearchManager.java │ │ │ ├── WebConfig.java │ │ │ ├── annotations │ │ │ └── PATCH.java │ │ │ ├── authentication │ │ │ └── AuthenticationHelper.java │ │ │ ├── config │ │ │ └── KeycloakConfigurationEndpoint.java │ │ │ ├── documents │ │ │ ├── DatabaseApplicationEndpoint.java │ │ │ ├── DatabaseEndpoint.java │ │ │ └── DocumentList.java │ │ │ ├── metrics │ │ │ ├── DashboardEndpoint.java │ │ │ └── PushMetricsEndpoint.java │ │ │ ├── registry │ │ │ ├── applications │ │ │ │ ├── AbstractVariantEndpoint.java │ │ │ │ ├── AdmVariantEndpoint.java │ │ │ │ ├── AliasEndpoint.java │ │ │ │ ├── AndroidVariantEndpoint.java │ │ │ │ ├── BootstrapEndpoint.java │ │ │ │ ├── InstallationManagementEndpoint.java │ │ │ │ ├── PushApplicationEndpoint.java │ │ │ │ ├── SimplePushVariantEndpoint.java │ │ │ │ ├── WindowsVariantEndpoint.java │ │ │ │ └── iOSVariantEndpoint.java │ │ │ └── installations │ │ │ │ ├── ExportEndpoint.java │ │ │ │ ├── ImporterForm.java │ │ │ │ └── InstallationRegistrationEndpoint.java │ │ │ ├── sender │ │ │ └── PushNotificationSenderEndpoint.java │ │ │ └── util │ │ │ ├── BearerHelper.java │ │ │ ├── BootstrapForm.java │ │ │ ├── ClientAuthHelper.java │ │ │ ├── CommonUtils.java │ │ │ ├── HealthCheck.java │ │ │ ├── HttpBasicHelper.java │ │ │ ├── HttpRequestUtil.java │ │ │ ├── PushAppAuthHelper.java │ │ │ └── iOSApplicationUploadForm.java │ └── resources │ │ ├── i18n │ │ └── messages.properties │ │ └── rest │ │ └── sender │ │ └── 100.json │ └── test │ ├── filtered-resources │ ├── cassandra-test-cql-dataload.cql │ └── default.properties │ ├── java │ └── org │ │ └── jboss │ │ └── aerogear │ │ └── unifiedpush │ │ └── rest │ │ ├── HeartbeatEndpointTest.java │ │ ├── IRestEndpointTest.java │ │ ├── LoggedIn.java │ │ ├── RandomPortTests.java │ │ ├── RestEndpointTest.java │ │ ├── RestNoRealtimedbTest.java │ │ ├── WebConfigTest.java │ │ ├── documents │ │ ├── DatabaseApplicationEndpointTest.java │ │ ├── DatabaseEndpointTest.java │ │ ├── DatabaseParseTest.java │ │ └── DocumentInstallationWrapper.java │ │ ├── registry │ │ ├── applications │ │ │ ├── InstallationManagementEndpointTest.java │ │ │ └── PushApplicationEndpointTest.java │ │ └── installations │ │ │ ├── AliasEndpointTest.java │ │ │ ├── InstallationRegistrationEndpointTest.java │ │ │ └── InstallationRegistrationNoAliasEndpointTest.java │ │ └── util │ │ ├── Authenticator.java │ │ ├── CommonUtilsTest.java │ │ ├── HealthStatusTest.java │ │ ├── HttpBasicHelperTest.java │ │ ├── HttpRequestHelperTest.java │ │ └── iOSApplicationUploadFormTest.java │ └── resources │ ├── META-INF │ ├── db.properties │ ├── hibernate.properties │ └── test-data.sql │ ├── application.properties │ ├── cert │ └── certificate.p12 │ ├── health-format.json │ └── logback.xml ├── migrator ├── README.md ├── liquibase-mysql-comparison.properties ├── liquibase-mysql-example.properties ├── liquibase-pgsql-comparison.properties ├── liquibase-postgresql-example.properties ├── pom.xml └── src │ ├── main │ ├── assembly │ │ └── dist.xml │ ├── java │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ └── migrator │ │ │ ├── CategoriesMigration.java │ │ │ ├── CertificateBlobToBase64.java │ │ │ ├── GetRidOfApiKeysMigration.java │ │ │ └── UniqueConstraintExistsCheck.java │ ├── resources │ │ └── liquibase │ │ │ ├── 1.0.0.Final │ │ │ ├── initial-mysql.xml │ │ │ ├── initial-pgsql.xml │ │ │ └── releasechanges.xml │ │ │ ├── 1.0.2 │ │ │ ├── 2014-12-17-keycloak-fixes.xml │ │ │ └── releasechanges.xml │ │ │ ├── 1.0.3 │ │ │ ├── 2014-10-16-add-category-entity.xml │ │ │ ├── 2015-01-22-change-blob-into-a-base64-string.xml │ │ │ ├── 2015-02-27-normalize_installations_table.xml │ │ │ └── releasechanges.xml │ │ │ ├── 1.1.0-Final │ │ │ ├── 2015-07-08-add-adm-variant-entity.xml │ │ │ ├── 2015-07-08-add-windows-variant-entities.xml │ │ │ ├── 2015-07-08-normalize-installation.xml │ │ │ ├── 2015-07-08-normalize-push-application.xml │ │ │ ├── 2015-07-08-normalize-push-message-information.xml │ │ │ ├── 2015-07-08-normalize-variants.xml │ │ │ ├── 2015-07-09-drop-chromepackagedapp-variant.xml │ │ │ ├── 2015-07-09-normalize-variant-metric-information.xml │ │ │ ├── 2015-07-10-disable-constraints.xml │ │ │ ├── 2015-07-10-reenable-constraints.xml │ │ │ └── releasechanges.xml │ │ │ ├── 1.2.0 │ │ │ ├── 2017-09-06-flat-model-entities.xml │ │ │ └── releasechanges.xml │ │ │ └── master.xml │ ├── scripts │ │ ├── recreate_db.sql │ │ ├── recreate_stable_db.sql │ │ ├── run-mysql │ │ └── run-pgsql │ └── shell │ │ └── ups-migrator │ └── test │ └── java │ └── org │ └── jboss │ └── aerogear │ └── unifiedpush │ └── migrator │ ├── EmbeddedMysqlDatabase.java │ └── MigratorTest.java ├── model ├── api │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ ├── api │ │ │ ├── AdmVariant.java │ │ │ ├── Alias.java │ │ │ ├── AndroidVariant.java │ │ │ ├── BaseModel.java │ │ │ ├── Category.java │ │ │ ├── FlatPushMessageInformation.java │ │ │ ├── IUser.java │ │ │ ├── Installation.java │ │ │ ├── InstallationVerificationAttempt.java │ │ │ ├── PushApplication.java │ │ │ ├── SimplePushVariant.java │ │ │ ├── Variant.java │ │ │ ├── VariantErrorStatus.java │ │ │ ├── VariantType.java │ │ │ ├── WindowsVariant.java │ │ │ ├── WindowsWNSVariant.java │ │ │ ├── document │ │ │ │ ├── DocumentMetadata.java │ │ │ │ ├── IDocument.java │ │ │ │ ├── IDocumentList.java │ │ │ │ └── QueryOptions.java │ │ │ ├── iOSVariant.java │ │ │ ├── validation │ │ │ │ ├── AlwaysFalseValidator.java │ │ │ │ ├── AlwaysTrueValidation.java │ │ │ │ ├── AlwaysTrueValidator.java │ │ │ │ ├── DeviceTokenCheck.java │ │ │ │ └── DeviceTokenValidator.java │ │ │ └── verification │ │ │ │ └── VerificationPublisher.java │ │ │ ├── dao │ │ │ ├── CategoryDao.java │ │ │ ├── FlatPushMessageInformationDao.java │ │ │ ├── GenericBaseDao.java │ │ │ ├── InstallationDao.java │ │ │ ├── PageResult.java │ │ │ ├── PushApplicationDao.java │ │ │ ├── ResultStreamException.java │ │ │ ├── ResultsStream.java │ │ │ ├── VariantDao.java │ │ │ └── helper │ │ │ │ └── InstallationAlias.java │ │ │ ├── dto │ │ │ ├── Count.java │ │ │ └── MessageMetrics.java │ │ │ ├── event │ │ │ └── iOSVariantUpdateEvent.java │ │ │ └── utils │ │ │ ├── DateUtils.java │ │ │ └── UUIDToDate.java │ │ └── test │ │ └── java │ │ └── org │ │ └── jboss │ │ └── aerogear │ │ └── unifiedpush │ │ └── api │ │ ├── AndroidVariantTest.java │ │ ├── FlatPushMessageInformationTest.java │ │ ├── InstallationTest.java │ │ ├── PushApplicationTest.java │ │ ├── iOSVariantTest.java │ │ └── validation │ │ └── DeviceTokenValidatorTest.java ├── jpa │ ├── .gitignore │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── jboss │ │ │ │ └── aerogear │ │ │ │ └── unifiedpush │ │ │ │ └── jpa │ │ │ │ ├── JPAConfig.java │ │ │ │ └── dao │ │ │ │ └── impl │ │ │ │ ├── JPABaseDao.java │ │ │ │ ├── JPACategoryDao.java │ │ │ │ ├── JPAFlatPushMessageInformationDao.java │ │ │ │ ├── JPAHealthDao.java │ │ │ │ ├── JPAInstallationDao.java │ │ │ │ ├── JPAPushApplicationDao.java │ │ │ │ └── JPAVariantDao.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── orm.xml │ │ │ ├── ValidationMessages.properties │ │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ └── api │ │ │ ├── Category.hbm.xml │ │ │ ├── FlatPushMessageInformation.hbm.xml │ │ │ ├── Installation.hbm.xml │ │ │ └── VariantErrorStatus.hbm.xml │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ ├── jpa │ │ │ ├── CategoryDaoTest.java │ │ │ ├── FlatPushMessageInformationDaoTest.java │ │ │ ├── InstallationDaoTest.java │ │ │ ├── JPAConfigTest.java │ │ │ ├── PersistentObjectTest.java │ │ │ ├── PushApplicationDaoTest.java │ │ │ └── VariantDaoTest.java │ │ │ └── utils │ │ │ └── TestUtils.java │ │ └── resources │ │ ├── AndroidVariant.xml │ │ ├── Categories.xml │ │ ├── FlatPushMessageInformation.xml │ │ ├── Installations.xml │ │ ├── META-INF │ │ ├── db.properties │ │ └── hibernate.properties │ │ ├── MessageInformation.xml │ │ ├── PushApplications.xml │ │ ├── Variant.xml │ │ ├── dbunit-express.properties │ │ └── logback.xml ├── nosql │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ └── cassandra │ │ │ ├── CassandraConfig.java │ │ │ ├── RetryCassandraSessionFactoryBean.java │ │ │ └── dao │ │ │ ├── AliasDao.java │ │ │ ├── CacheConfig.java │ │ │ ├── DatabaseDao.java │ │ │ ├── DistinctUitils.java │ │ │ ├── DocumentDao.java │ │ │ ├── NullAlias.java │ │ │ ├── NullUUID.java │ │ │ ├── impl │ │ │ ├── AliasAlreadyExists.java │ │ │ ├── CassandraBaseDao.java │ │ │ ├── DocumentKey.java │ │ │ ├── NoSQLDatabaseDaoImpl.java │ │ │ ├── NoSQLDocumentDaoImpl.java │ │ │ └── NoSQLUserDaoImpl.java │ │ │ └── model │ │ │ ├── Database.java │ │ │ ├── DatabaseKey.java │ │ │ ├── DatabaseQueryKey.java │ │ │ ├── DocumentContent.java │ │ │ ├── User.java │ │ │ ├── UserKey.java │ │ │ └── parser │ │ │ ├── JsonDocumentContent.java │ │ │ ├── JsonRawValueDeserializer.java │ │ │ └── UnsupportedContentTypeException.java │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ └── cassandra │ │ │ └── test │ │ │ └── integration │ │ │ ├── CassandraUnitTestClassExecutionListener.java │ │ │ ├── FixedKeyspaceCreatingIntegrationTest.java │ │ │ ├── UUIDToDateTest.java │ │ │ └── dao │ │ │ ├── NoSQLAliasDaoTest.java │ │ │ ├── NoSQLDatabaseDaoTest.java │ │ │ └── NoSQLDocumentDaoTest.java │ │ └── resources │ │ ├── cassandra-test-cql-dataload.cql │ │ ├── default.properties │ │ └── logback.xml ├── pom.xml └── push │ ├── pom.xml │ └── src │ ├── main │ └── java │ │ └── org │ │ └── jboss │ │ └── aerogear │ │ └── unifiedpush │ │ └── message │ │ ├── Config.java │ │ ├── Criteria.java │ │ ├── Message.java │ │ ├── Priority.java │ │ ├── UnifiedPushMessage.java │ │ ├── apns │ │ └── APNs.java │ │ ├── json │ │ ├── PriorityDeserializer.java │ │ └── PrioritySerializer.java │ │ └── windows │ │ ├── BadgeType.java │ │ ├── DurationType.java │ │ ├── TileType.java │ │ ├── ToastType.java │ │ ├── Type.java │ │ └── Windows.java │ └── test │ ├── java │ └── org │ │ └── jboss │ │ └── aerogear │ │ └── unifiedpush │ │ └── message │ │ └── UnifiedPushMessageTest.java │ └── resources │ ├── message-format.json │ ├── message-high-priority.json │ ├── message-normal-priority.json │ ├── message-tojson.json │ └── message-tostrippedjson.json ├── node.js ├── README.md └── directgranttest.js ├── openshift ├── README.md └── ups-template.json ├── pom.xml ├── push-sender ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ └── message │ │ │ ├── HealthNetworkService.java │ │ │ ├── InternalUnifiedPushMessage.java │ │ │ ├── NotificationDispatcher.java │ │ │ ├── NotificationRouter.java │ │ │ ├── SenderConfig.java │ │ │ ├── cache │ │ │ ├── AbstractServiceCache.java │ │ │ ├── ServiceConstructor.java │ │ │ └── SimpleApnsClientCache.java │ │ │ ├── configuration │ │ │ ├── SenderConfiguration.java │ │ │ └── SenderConfigurationProvider.java │ │ │ ├── event │ │ │ ├── AllBatchesLoadedEvent.java │ │ │ └── BatchLoadedEvent.java │ │ │ ├── exception │ │ │ ├── DispatchInitiationException.java │ │ │ ├── MessageDeliveryException.java │ │ │ ├── PushNetworkUnreachableException.java │ │ │ └── SenderResourceNotAvailableException.java │ │ │ ├── holder │ │ │ ├── AbstractMessageHolder.java │ │ │ ├── MessageHolderWithTokens.java │ │ │ └── MessageHolderWithVariants.java │ │ │ ├── sender │ │ │ ├── AdmPushNotificationSender.java │ │ │ ├── FCMPushNotificationSender.java │ │ │ ├── NotificationSenderCallback.java │ │ │ ├── PushNotificationSender.java │ │ │ ├── SimplePushNotificationSender.java │ │ │ ├── WNSPushNotificationSender.java │ │ │ ├── apns │ │ │ │ ├── ApnsUtil.java │ │ │ │ └── PushyApnsSender.java │ │ │ └── fcm │ │ │ │ └── ConfigurableFCMSender.java │ │ │ ├── token │ │ │ ├── TokenLoader.java │ │ │ └── TokenLoaderUtils.java │ │ │ └── util │ │ │ └── HealthNetworkServiceImpl.java │ └── resources │ │ └── META-INF │ │ └── beans.xml │ └── test │ ├── filtered-resources │ ├── cassandra-test-cql-dataload.cql │ └── default.properties │ ├── java │ └── org │ │ └── jboss │ │ └── aerogear │ │ └── unifiedpush │ │ └── message │ │ ├── DeviceTokenValidatorTest.java │ │ ├── TestNotificationRouter.java │ │ ├── TestNotificationRouterTopic.java │ │ ├── configuration │ │ └── TestSenderConfigurationProducer.java │ │ ├── jms │ │ ├── TestMessageHolderWithTokens.java │ │ ├── TestMessageRedelivery.java │ │ └── TestTokenBatchDeduplication.java │ │ ├── sender │ │ └── WNSPushNotificationSenderTest.java │ │ └── token │ │ └── TokenLoaderUtilsTest.java │ └── resources │ ├── META-INF │ ├── db.properties │ ├── hibernate.properties │ └── test-data.sql │ ├── cert │ └── certificate.p12 │ └── logback.xml ├── servers ├── README.txt ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── jboss │ │ └── aerogear │ │ └── unifiedpush │ │ └── auth │ │ ├── BasicAuthenticationRequestMatcher.java │ │ ├── CustomKeycloakDeployment.java │ │ ├── CustomKeycloakDeploymentBuilder.java │ │ ├── PathBasedKeycloakConfigResolver.java │ │ └── SecurityConfig.java │ ├── resources │ ├── META-INF │ │ ├── db.properties │ │ └── hibernate.properties │ └── default.properties │ └── webapp │ ├── META-INF │ ├── MANIFEST.MF │ └── log4j.xml │ └── WEB-INF │ ├── applicationContext.xml │ ├── jboss-deployment-structure.xml │ ├── jboss-web.xml │ ├── keycloak-proxy.json │ ├── keycloak.json │ └── web.xml ├── service ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── jboss │ │ │ └── aerogear │ │ │ └── unifiedpush │ │ │ ├── service │ │ │ ├── AliasService.java │ │ │ ├── ClientInstallationAsyncService.java │ │ │ ├── ClientInstallationService.java │ │ │ ├── DocumentService.java │ │ │ ├── GenericVariantService.java │ │ │ ├── HealthDBService.java │ │ │ ├── PostDelete.java │ │ │ ├── PushApplicationService.java │ │ │ ├── PushSearchService.java │ │ │ ├── annotations │ │ │ │ └── LoggedInUser.java │ │ │ ├── dashboard │ │ │ │ ├── Application.java │ │ │ │ ├── ApplicationVariant.java │ │ │ │ └── DashboardData.java │ │ │ ├── impl │ │ │ │ ├── AliasServiceImpl.java │ │ │ │ ├── ClientInstallationAsyncServiceImpl.java │ │ │ │ ├── ClientInstallationServiceImpl.java │ │ │ │ ├── DocumentServiceImpl.java │ │ │ │ ├── GenericVariantServiceImpl.java │ │ │ │ ├── HealthServiceImpl.java │ │ │ │ ├── PushApplicationServiceImpl.java │ │ │ │ ├── PushSearchByDeveloperServiceImpl.java │ │ │ │ ├── PushSearchServiceImpl.java │ │ │ │ ├── ServiceConstraintViolationException.java │ │ │ │ ├── health │ │ │ │ │ ├── HealthDetails.java │ │ │ │ │ ├── HealthStatus.java │ │ │ │ │ ├── Ping.java │ │ │ │ │ ├── PushNetwork.java │ │ │ │ │ └── Status.java │ │ │ │ └── spring │ │ │ │ │ ├── ConfigurationServiceImpl.java │ │ │ │ │ ├── IConfigurationService.java │ │ │ │ │ ├── IKeycloakService.java │ │ │ │ │ ├── IOAuth2Configuration.java │ │ │ │ │ ├── KeycloakServiceImpl.java │ │ │ │ │ └── OAuth2Configuration.java │ │ │ ├── metrics │ │ │ │ ├── DeleteOldPushMessageInformationScheduler.java │ │ │ │ ├── IPushMessageMetricsService.java │ │ │ │ └── PushMessageMetricsService.java │ │ │ ├── proxy │ │ │ │ └── ProxyConfiguration.java │ │ │ ├── util │ │ │ │ └── FCMTopicManager.java │ │ │ └── validation │ │ │ │ ├── ApplicationValidation.java │ │ │ │ ├── ApplicationValidator.java │ │ │ │ ├── ConstraintValidatorContextImpl.java │ │ │ │ ├── PhoneValidation.java │ │ │ │ └── PhoneValidator.java │ │ │ └── spring │ │ │ ├── ServiceCacheConfig.java │ │ │ └── ServiceConfig.java │ └── resources │ │ ├── META-INF │ │ └── beans.xml │ │ ├── applicationContext.xml │ │ └── realm.json │ └── test │ ├── filtered-resources │ ├── cassandra-test-cql-dataload.cql │ └── default.properties │ ├── java │ └── org │ │ └── jboss │ │ └── aerogear │ │ └── unifiedpush │ │ └── service │ │ ├── AbstractBaseServiceTest.java │ │ ├── AbstractCassandraServiceTest.java │ │ ├── AbstractNoCassandraServiceTest.java │ │ ├── AliasServiceTest.java │ │ ├── CassandraUnitTestClassExecutionListener.java │ │ ├── ClientInstallationServiceTest.java │ │ ├── DocumentServiceTest.java │ │ ├── PushApplicationServiceTest.java │ │ ├── PushMessageMetricServiceTest.java │ │ ├── TestUtils.java │ │ ├── impl │ │ └── health │ │ │ └── PingTest.java │ │ └── spring │ │ ├── AccountNameMatcherTest.java │ │ ├── ConfigurationTest.java │ │ └── KeycloakServiceTest.java │ └── resources │ ├── META-INF │ ├── beans.xml │ ├── db.properties │ ├── hibernate.properties │ └── test-data.sql │ ├── cert │ └── certificate.p12 │ └── logback.xml ├── ups-home-ui-screenshot.png └── ups-ui-screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | 8 | #Build targets 9 | target/ 10 | /target 11 | */target 12 | access_log* 13 | 14 | #Maven release files 15 | *.releaseBackup 16 | release.properties 17 | 18 | .idea/ 19 | *.class 20 | *.iml 21 | .classpath 22 | .project 23 | .settings/ 24 | .metadata 25 | 26 | .DS_Store 27 | *.checkstyle 28 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "keycloak"] 2 | path = keycloak 3 | url = https://github.com/aerobase/unifiedpush-keycloak-spi.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | sudo: false 4 | 5 | # required for oraclejdk9 6 | dist: trusty 7 | 8 | # required for oraclejdk9 9 | group: edge 10 | 11 | cache: 12 | directories: 13 | - $HOME/.m2 14 | 15 | jdk: 16 | - openjdk8 17 | - oraclejdk8 18 | - oraclejdk9 19 | 20 | matrix: 21 | allow_failures: 22 | - jdk: oraclejdk9 23 | 24 | branches: 25 | only: 26 | - master 27 | 28 | before_install: 29 | - "npm install -g grunt-cli bower@1.3.9" 30 | 31 | before_script: 32 | - jdk_switcher use $JDK 33 | 34 | script: "mvn verify javadoc:jar" 35 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | This project includes fonts under SIL OPEN FONT LICENSE Version 1.1: 2 | 3 | admin-ui/app/styles/fonts/exo2/* 4 | Copyright (C) 2013, Natanael Gama -------------------------------------------------------------------------------- /common/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /databases/docker-compose/mysql-database-config-wildfly.cli: -------------------------------------------------------------------------------- 1 | # $WILDFLY_HOME/bin/jboss-cli.sh --file=/path/to/this/file. 2 | connect 3 | batch 4 | 5 | ## Add Mysql driver 6 | /subsystem=datasources/jdbc-driver=mysqlup:add(driver-name=mysqlup,driver-module-name=com.mysql.jdbc,driver-xa-datasource-class-name=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource) 7 | 8 | ## Add UnifiedPush Datasource 9 | data-source add --name=UnifiedPushDS --driver-name=mysqlup --jndi-name=java:jboss/datasources/UnifiedPushDS --connection-url="jdbc:mysql://localhost:6306/unifiedpush?useUnicode=true&characterEncoding=UTF-8" --user-name=unifiedpush --password=unifiedpush --use-ccm=false --max-pool-size=25 --blocking-timeout-wait-millis=5000 --enabled=true 10 | 11 | run-batch 12 | #:reload 13 | -------------------------------------------------------------------------------- /databases/docker-compose/ups-datasource.yml: -------------------------------------------------------------------------------- 1 | unifiedpush: 2 | image: mysql:5.5 3 | environment: 4 | - MYSQL_USER=unifiedpush 5 | - MYSQL_PASSWORD=unifiedpush 6 | - MYSQL_DATABASE=unifiedpush 7 | - MYSQL_ROOT_PASSWORD=supersecret 8 | ports: 9 | - 6306:3306 10 | -------------------------------------------------------------------------------- /databases/docker-compose/ups-galera-cluster.yml: -------------------------------------------------------------------------------- 1 | # Galera cluster config, modified from 2 | # https://gist.github.com/lucidfrontier45/497341c4b848dfbd6dfb 3 | 4 | upsnode1: 5 | image: hauptmedia/mariadb:10.1 6 | hostname: upsnode1 7 | ports: 8 | - 13306:3306 9 | environment: 10 | - MYSQL_ROOT_PASSWORD=unifiedpush 11 | - REPLICATION_PASSWORD=unifiedpush 12 | - MYSQL_DATABASE=unifiedpush 13 | - MYSQL_USER=unifiedpush 14 | - MYSQL_PASSWORD=unifiedpush 15 | - GALERA=On 16 | - NODE_NAME=upsnode1 17 | - CLUSTER_NAME=maria_cluster 18 | - CLUSTER_ADDRESS=gcomm:// 19 | command: --wsrep-new-cluster 20 | 21 | upsnode2: 22 | image: hauptmedia/mariadb:10.1 23 | hostname: upsnode2 24 | links: 25 | - upsnode1 26 | ports: 27 | - 23306:3306 28 | environment: 29 | - REPLICATION_PASSWORD=unifiedpush 30 | - GALERA=On 31 | - NODE_NAME=upsnode2 32 | - CLUSTER_NAME=maria_cluster 33 | - CLUSTER_ADDRESS=gcomm://upsnode1 34 | 35 | upsnode3: 36 | image: hauptmedia/mariadb:10.1 37 | hostname: upsnode3 38 | links: 39 | - upsnode1 40 | ports: 41 | - 33306:3306 42 | environment: 43 | - REPLICATION_PASSWORD=unifiedpush 44 | - GALERA=On 45 | - NODE_NAME=upsnode3 46 | - CLUSTER_NAME=maria_cluster 47 | - CLUSTER_ADDRESS=gcomm://upsnode1 48 | -------------------------------------------------------------------------------- /databases/h2-database-config-wildfly.cli: -------------------------------------------------------------------------------- 1 | # $WILDFLY_HOME/bin/jboss-cli.sh --file=/path/to/this/file. 2 | connect 3 | batch 4 | 5 | ## Add UnifiedPush Datasource 6 | data-source add --name=UnifiedPushDS --driver-name=h2 --jndi-name=java:jboss/datasources/UnifiedPushDS --connection-url="jdbc:h2:${jboss.server.data.dir}/unifiedpush;DB_CLOSE_DELAY=-1" --user-name=sa --password=sa --use-ccm=true --enabled=true 7 | 8 | run-batch 9 | #:reload 10 | -------------------------------------------------------------------------------- /databases/ha_deployment/deploy-managed-domain.cli: -------------------------------------------------------------------------------- 1 | connect 2 | batch 3 | 4 | deploy ag-push.war --server-groups=other-server-group 5 | 6 | run-batch 7 | #:reload -------------------------------------------------------------------------------- /databases/ha_deployment/mysql-database-config-wildfly-full-ha.cli: -------------------------------------------------------------------------------- 1 | # $WILDFLY_HOME/bin/jboss-cli.sh --file=/path/to/this/file. 2 | connect localhost:10190 3 | batch 4 | 5 | ## Add Mysql driver 6 | /subsystem=datasources/jdbc-driver=mysqlup:add(driver-name=mysqlup,driver-module-name=com.mysql.jdbc,driver-xa-datasource-class-name=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource) 7 | 8 | ## Add UnifiedPush Datasource 9 | data-source add --name=UnifiedPushDS --driver-name=mysqlup --jndi-name=java:jboss/datasources/UnifiedPushDS --connection-url="jdbc:mysql://192.168.59.104:6306/unifiedpush?useUnicode=true&characterEncoding=UTF-8" --user-name=unifiedpush --password=unifiedpush --use-ccm=false --max-pool-size=25 --blocking-timeout-wait-millis=5000 --enabled=true 10 | 11 | run-batch 12 | #:reload 13 | -------------------------------------------------------------------------------- /databases/ha_deployment/mysql-database-config-wildfly-managed-domain.cli: -------------------------------------------------------------------------------- 1 | # $WILDFLY_HOME/bin/jboss-cli.sh --file=/path/to/this/file. 2 | connect 3 | batch 4 | 5 | ## Add Mysql driver 6 | /profile=full-ha/subsystem=datasources/jdbc-driver=mysqlup:add(driver-name=mysqlup,driver-module-name=com.mysql.jdbc,driver-xa-datasource-class-name=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource) 7 | 8 | ## Add UnifiedPush Datasource 9 | data-source add --profile=full-ha --name=UnifiedPushDS --driver-name=mysqlup --jndi-name=java:jboss/datasources/UnifiedPushDS --connection-url="jdbc:mysql://192.168.59.104:6306/unifiedpush?useUnicode=true&characterEncoding=UTF-8" --user-name=unifiedpush --password=unifiedpush --use-ccm=false --max-pool-size=25 --blocking-timeout-wait-millis=5000 --enabled=true 10 | 11 | run-batch 12 | #:reload 13 | -------------------------------------------------------------------------------- /databases/initdb/src/main/java/org/jboss/aerogear/unifiedpush/DBMaintenance.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush; 2 | 3 | import org.jboss.aerogear.unifiedpush.jpa.JPAConfig; 4 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 5 | 6 | public class DBMaintenance { 7 | public static void main(final String[] args) { 8 | // Initialize spring context to create DB schema 9 | AnnotationConfigApplicationContext applicationContext = null; 10 | 11 | System.out.println("Using config path from " + System.getProperty("aerobase.config.dir")); 12 | 13 | applicationContext = createApplicationContext(); 14 | 15 | if (null != applicationContext) { 16 | applicationContext.close(); 17 | } 18 | 19 | System.exit(0); 20 | } 21 | 22 | public static AnnotationConfigApplicationContext createApplicationContext() { 23 | final AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 24 | ctx.register(JPAConfig.class); 25 | ctx.refresh(); 26 | 27 | return ctx; 28 | } 29 | 30 | public static AnnotationConfigApplicationContext inititializeApplicationContext() { 31 | final AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 32 | ctx.register(JPAConfig.class); 33 | ctx.refresh(); 34 | 35 | return ctx; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /databases/initdb/src/main/resources/META-INF/db.properties: -------------------------------------------------------------------------------- 1 | # Postgres connection string 2 | jdbcUrl=jdbc:postgresql://localhost:5432/unifiedpush_server 3 | username=aerobase_server 4 | password= 5 | 6 | dataSource.dataSource=true 7 | dataSource.prepStmtCacheSize=250 8 | dataSource.prepStmtCacheSqlLimit=2048 9 | dataSource.useServerPrepStmts=true 10 | 11 | # Maximum number of JDBC connections in the pool. 12 | maximumPoolSize=25 13 | # Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire. Default: 300 14 | idleTimeout=300 -------------------------------------------------------------------------------- /databases/initdb/src/main/resources/META-INF/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.dialect=org.hibernate.dialect.PostgreSQL95Dialect 2 | hibernate.hbm2ddl.auto=update 3 | hibernate.show_sql=false 4 | hibernate.format_sql=false 5 | hibernate.transaction.flush_before_completion=true 6 | hibernate.id.new_generator_mappings=true -------------------------------------------------------------------------------- /databases/initdb/src/main/resources/bin/cassandra-keyspace.cql: -------------------------------------------------------------------------------- 1 | CREATE KEYSPACE IF NOT EXISTS unifiedpush_server WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 2}; -------------------------------------------------------------------------------- /databases/initdb/src/main/resources/bin/init-cassandra-db.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "${JAVA_HOME}" ]; then 4 | # Gentoo 5 | if which java-config > /dev/null 2>&1; then 6 | export JAVA_HOME="$(java-config --jre-home)" 7 | else 8 | export JAVA_HOME="/usr" 9 | fi 10 | fi 11 | 12 | die() { 13 | local localmsg="$1" 14 | echo "FATAL: ${localmsg}" >&2 15 | exit 1 16 | } 17 | 18 | keyspace="$1" 19 | [ -z "${keyspace}" ] && die "Missing keyspace! Usage: ./init-cassandra-db.sh keyspace-name" 20 | 21 | #remote debug parameters 22 | #export DEBUG_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=y" 23 | 24 | # TODO - Support username password, e.g -u myusername -p mypassword localhost 25 | # TODO - Use keyspace parameter in .cql files. 26 | cqlsh -f cassandra-keyspace.cql >> /tmp/init-cassandra.log 27 | cqlsh -f cassandra-tables.cql >> /tmp/init-cassandra.log 28 | -------------------------------------------------------------------------------- /databases/initdb/src/main/resources/bin/init-unifiedpush-db.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | IF %1.==. GOTO No1 3 | set CONFIG=%1 4 | 5 | REM set debug parameters 6 | REM set DEBUG_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=y" 7 | 8 | "%JAVA_HOME%\bin\java" -cp ..\lib\* %DEBUG_OPTS% "-Daerobase.config.dir=%CONFIG%" "-Djava.library.path=..\\..\\..\\mssql" org.jboss.aerogear.unifiedpush.DBMaintenance > initdb-java.log 2>&1 9 | 10 | GOTO End1 11 | 12 | :No1 13 | ECHO Missing Config file 14 | GOTO End1 15 | 16 | :End1 17 | @ECHO ON 18 | -------------------------------------------------------------------------------- /databases/initdb/src/main/resources/bin/init-unifiedpush-db.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "${JAVA_HOME}" ]; then 4 | # Gentoo 5 | if which java-config > /dev/null 2>&1; then 6 | export JAVA_HOME="$(java-config --jre-home)" 7 | else 8 | export JAVA_HOME="/usr" 9 | fi 10 | fi 11 | 12 | die() { 13 | local localmsg="$1" 14 | echo "FATAL: ${localmsg}" >&2 15 | exit 1 16 | } 17 | 18 | #remote debug parameters 19 | #export DEBUG_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=y" 20 | 21 | while [ -n "$1" ]; do 22 | v="${1#*=}" 23 | case "$1" in 24 | --config-path=*) 25 | export CONFIG="${v}" 26 | ;; 27 | --help|*) 28 | cat <<__EOF__ 29 | Usage: $0 30 | --config-path=path - Path for -Daerobase.config.dir param - Default /tmp/ 31 | __EOF__ 32 | exit 1 33 | esac 34 | shift 35 | done 36 | 37 | [ -z "${CONFIG}" ] && export CONFIG=/tmp/ 38 | 39 | ${JAVA_HOME}/bin/java ${DEBUG_OPTS} \ 40 | -Daerobase.config.dir=${CONFIG} \ 41 | -cp "../lib/*" \ 42 | org.jboss.aerogear.unifiedpush.DBMaintenance 43 | -------------------------------------------------------------------------------- /databases/migration/README.md: -------------------------------------------------------------------------------- 1 | # UnifiedPush Server - Database migration 2 | 3 | For the database migration you may need to run a few scripts inside of the database 4 | 5 | ## 1.0.0 users 6 | 7 | The UnifiedPush Server is supporting two different databases, MySQL and PostgreSQL, below you find information on how to perform the migration on each of the supported databases 8 | 9 | ### MySQL 10 | 11 | Inside of the database execute these two scripts: 12 | 13 | * `keycloak-migration-mysql.sql` 14 | * `ups-migration-mysql.sql` 15 | 16 | ### PostgreSQL 17 | 18 | Inside of the database execute these two scripts: 19 | 20 | * `keycloak-migration-postgresql.sql` 21 | * `ups-migration-postgresql.sql` 22 | 23 | ### WAR files 24 | 25 | After successfully executing the above migration scripts you need to replace the deployed 1.0.0 WAR files with the new ones. That's it! 26 | 27 | ## 1.0.1 or 1.0.2 users 28 | 29 | No migration is required :smile: 30 | -------------------------------------------------------------------------------- /databases/migration/keycloak-migration-mysql.sql: -------------------------------------------------------------------------------- 1 | use unifiedpush; 2 | 3 | -- 4 | -- Migrate KC refactorings done between 1.0-beta-4 and 1.0.Final 5 | -- 6 | rename table REALM_AUDIT_LISTENERS to REALM_EVENTS_LISTENERS; 7 | alter table REALM change AUDIT_ENABLED EVENTS_ENABLED bit(1); 8 | alter table REALM change AUDIT_EXPIRATION EVENTS_EXPIRATION bigint(20); 9 | -------------------------------------------------------------------------------- /databases/migration/keycloak-migration-postgresql.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Migrate KC refactorings done between 1.0-beta-4 and 1.0.Final 3 | -- 4 | alter table REALM_AUDIT_LISTENERS rename to REALM_EVENTS_LISTENERS; 5 | alter table REALM rename column AUDIT_ENABLED to EVENTS_ENABLED; 6 | alter table REALM rename column AUDIT_EXPIRATION to EVENTS_EXPIRATION; 7 | -------------------------------------------------------------------------------- /databases/migration/ups-migration-mysql.sql: -------------------------------------------------------------------------------- 1 | use unifiedpush; 2 | 3 | CREATE TABLE `hibernate_sequence` ( 4 | `next_val` BIGINT(19) NOT NULL 5 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 6 | 7 | -- 8 | -- Table structure for table `Category` 9 | -- 10 | 11 | CREATE TABLE `Category` ( 12 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 13 | `name` varchar(255) DEFAULT NULL, 14 | PRIMARY KEY (`id`) 15 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 16 | 17 | -- -------------------------------------------------------- 18 | 19 | -- 20 | -- Table structure for table `Installation_Category` 21 | -- 22 | 23 | CREATE TABLE `Installation_Category` ( 24 | `Installation_id` varchar(255) NOT NULL, 25 | `categories_id` bigint(20) NOT NULL, 26 | PRIMARY KEY (`Installation_id`,`categories_id`), 27 | KEY `FK9A83A563DC2D45CD` (`Installation_id`), 28 | KEY `FK9A83A563B9183AEF` (`categories_id`) 29 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 30 | 31 | 32 | -- 33 | -- Migrate data from `Installation_categories` to `Installation_Category` 34 | -- 35 | 36 | insert into Category (name) select distinct categories from Installation_categories; 37 | insert into Installation_Category SELECT installation_id, id FROM Installation_categories ic join Category c on c.name = ic.categories; 38 | 39 | insert into hibernate_sequence (next_val) select max(id) + 1 from Category; 40 | 41 | drop table Installation_categories; 42 | -------------------------------------------------------------------------------- /databases/migration/ups-migration-postgresql.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Table structure for table `Category` 3 | -- 4 | 5 | CREATE TABLE Category ( 6 | id SERIAL NOT NULL, 7 | name varchar(255), 8 | PRIMARY KEY (id) 9 | ); 10 | 11 | -- -------------------------------------------------------- 12 | 13 | -- 14 | -- Table structure for table `Installation_Category` 15 | -- 16 | 17 | CREATE TABLE Installation_Category ( 18 | Installation_id varchar(255) NOT NULL references Installation(id), 19 | categories_id bigint NOT NULL references Category(id), 20 | PRIMARY KEY (Installation_id,categories_id) 21 | ); 22 | 23 | -- 24 | -- Migrate data from `Installation_categories` to `Installation_Category` 25 | -- 26 | 27 | insert into Category (name) select distinct categories from Installation_categories; 28 | insert into Installation_Category SELECT installation_id, id FROM Installation_categories ic join Category c on c.name = ic.categories; 29 | 30 | drop table installation_categories; -------------------------------------------------------------------------------- /databases/mysql-database-config-wildfly.cli: -------------------------------------------------------------------------------- 1 | # $WILDFLY_HOME/bin/jboss-cli.sh --file=/path/to/this/file. 2 | connect 3 | batch 4 | 5 | ## Add Mysql driver 6 | /subsystem=datasources/jdbc-driver=mysqlup:add(driver-name=mysqlup,driver-module-name=com.mysql.jdbc,driver-xa-datasource-class-name=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource) 7 | 8 | ## Add UnifiedPush Datasource 9 | data-source add --name=UnifiedPushDS --driver-name=mysqlup --jndi-name=java:jboss/datasources/UnifiedPushDS --connection-url="jdbc:mysql://localhost:6306/unifiedpush?useUnicode=true&characterEncoding=UTF-8" --user-name=unifiedpush --password=unifiedpush --use-ccm=false --max-pool-size=25 --blocking-timeout-wait-millis=5000 --enabled=true 10 | 11 | run-batch 12 | #:reload 13 | -------------------------------------------------------------------------------- /databases/postgresql-database-config-wildfly.cli: -------------------------------------------------------------------------------- 1 | # $WILDFLY_HOME/bin/jboss-cli.sh --file=/path/to/this/file. 2 | connect 3 | batch 4 | 5 | ## Add Postgresql driver 6 | /subsystem=datasources/jdbc-driver=psqlup:add(driver-name=psqlup,driver-module-name=org.postgresql,driver-xa-datasource-class-name=org.postgresql.xa.PGXADataSource) 7 | 8 | ## Add UnifiedPush Datasource 9 | data-source add --name=UnifiedPushDS --driver-name=psqlup --jndi-name=java:jboss/datasources/UnifiedPushDS --connection-url=jdbc:postgresql://localhost:5432/unifiedpush --user-name=unifiedpush --password=unifiedpush --use-ccm=false --max-pool-size=25 --blocking-timeout-wait-millis=5000 --enabled=true 10 | 11 | run-batch 12 | #:reload 13 | -------------------------------------------------------------------------------- /databases/prepare_clean_wf11.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! "$WILDFLY_HOME" ]; then 4 | printf "Error: Please configure the installation path for WildFly\n" 5 | printf " >>> Ex: WILDFLY_HOME=/path/to/your/wildfly11-installation\n" 6 | exit 1 7 | else 8 | printf "😂 Awesome, WildFly 11 is configured!\n" 9 | printf " >>> Preparing the MySQL DB module\n" 10 | cp -r ./src/main/resources/modules/com $WILDFLY_HOME/modules 11 | mvn dependency:copy -Dartifact=mysql:mysql-connector-java:5.1.18 -DoutputDirectory=$WILDFLY_HOME/modules/com/mysql/jdbc/main/ 12 | printf "WildFly 11 DB configuration is about to start\n" 13 | printf " >>> Running the jboss-cli tool!\n" 14 | $WILDFLY_HOME/bin/jboss-cli.sh --file=./mysql-database-config-wildfly.cli 15 | 16 | printf "WildFly 11 JMS configuration is about to start\n" 17 | printf " >>> Running the jboss-cli tool!\n" 18 | $WILDFLY_HOME/bin/jboss-cli.sh --file=../configuration/jms-setup-wildfly.cli 19 | 20 | printf "Huzza, it worked!\n" 21 | 22 | fi 23 | exit 0 24 | -------------------------------------------------------------------------------- /databases/src/main/resources/modules/com/mysql/jdbc/main/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /databases/src/main/resources/modules/org/postgresql/main/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /databases/unifiedpush-h2-ds.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | jdbc:h2:${jboss.server.data.dir}/unifiedpush;DB_CLOSE_DELAY=-1 21 | h2 22 | 23 | sa 24 | sa 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /dist/README.md: -------------------------------------------------------------------------------- 1 | # AeroGear UnifiedPush Server - Release Bundle 2 | 3 | The content of this archive contains: 4 | * Keycloak development setup, via docker-compose 5 | * database configuration files and modules for WildFly10/11 6 | * WAR file for UnifiedPush Server (for WildFly) 7 | * source JAR files of the UnifiedPush Server for debugging. 8 | 9 | To learn more about how to configure and install the UnifiedPush Server please visit our user guide: 10 | http://aerogear.org/push 11 | 12 | -------------------------------------------------------------------------------- /docker-compose/development/README.md: -------------------------------------------------------------------------------- 1 | # Keycloak and MySQL - Development Environment 2 | 3 | For running UPS, you need a database and a running Keycloak broker. This folder contains a _development_ environment, that spins up a MySQL 5.x DB and a Keycloak server that imports our demo realm. 4 | 5 | ## Getting started 6 | 7 | To run these servers, simply execute the following command: 8 | 9 | ``` 10 | docker-compose -f development-env.yaml up 11 | ``` 12 | 13 | ## Running the UPS 14 | 15 | To run the UPS `WAR` file, you need to know the IP address of the keycloak broker, you can extract it like: 16 | 17 | ``` 18 | docker inspect --format '{{ .NetworkSettings.IPAddress }}' name_or_id_of_the_keycloak_container 19 | ``` 20 | 21 | That value needs to be used when launching the _prepared_ WildFly11 container, like: 22 | 23 | ``` 24 | /$WF_HOME/bin/standalone.sh -Dups.realm.name=aerogear -Dups.auth.server.url=http://172.17.0.7:8080/auth -b 0.0.0.0 25 | 26 | ``` 27 | 28 | **NOTE:** This is for development only - in production you should not use wildcard URLs! 29 | 30 | 31 | -------------------------------------------------------------------------------- /docker-compose/development/development-env.yaml: -------------------------------------------------------------------------------- 1 | keycloakServer: 2 | image: jboss/keycloak:3.2.1.Final 3 | command: "-b 0.0.0.0 -Dkeycloak.import=/ups-keycloak-config/ups-realm-sample.json" 4 | volumes: 5 | - ./ups-realm:/ups-keycloak-config 6 | environment: 7 | - KEYCLOAK_USER=admin 8 | - KEYCLOAK_PASSWORD=admin 9 | unifiedpushDB: 10 | image: mysql:5.5 11 | environment: 12 | - MYSQL_USER=unifiedpush 13 | - MYSQL_PASSWORD=unifiedpush 14 | - MYSQL_DATABASE=unifiedpush 15 | - MYSQL_ROOT_PASSWORD=supersecret 16 | ports: 17 | - 6306:3306 18 | -------------------------------------------------------------------------------- /docker-compose/ups-master/.env: -------------------------------------------------------------------------------- 1 | # env vars for interpolate mysql and app server services 2 | MYSQL_USER=unifiedpush 3 | MYSQL_PASSWORD=unifiedpush 4 | MYSQL_ROOT_PASSWORD=supersecret 5 | MYSQL_DATABASE_UNIFIEDPUSH=unifiedpush 6 | MYSQL_ADDR_UNIFIEDPUSH=unifiedpush 7 | MYSQL_DATABASE_KEYCLOAK=keycloak 8 | MYSQL_ADDR_KEYCLOAK=keycloak 9 | MYSQL_PORT_3306_TCP_PORT=3306 -------------------------------------------------------------------------------- /docker-compose/ups-master/README.md: -------------------------------------------------------------------------------- 1 | # UnifiedPush Server - Docker Compose 2 | 3 | The quickest way to run the latest version of the UPS is running it [Docker Dev image](https://github.com/jboss-dockerfiles/aerogear/tree/master/wildfly/unifiedpush-wildfly-dev#running-the-image). 4 | 5 | But this still requires a few commands, to launch the required DB and the server itself. To fasten the process `cd` into this folder and use our Docker Compose files: 6 | 7 | | Compose File Version | Docker Engine Version | 8 | |------------------------- |----------------------- | 9 | | docker-compose-v1.yaml | 1.9.1.+ | 10 | | docker-compose-v3x.yaml | 1.13.0+ | 11 | 12 | 13 | ``` 14 | docker-compose -f docker-compose-v1.yaml up -d 15 | ``` 16 | 17 | This fires up all the components you need and finally launches the UPS at: `https:DOCKER_IP:8443/ag-push` 18 | -------------------------------------------------------------------------------- /docker-compose/ups-master/docker-compose-v1.yaml: -------------------------------------------------------------------------------- 1 | unifiedpushDB: 2 | image: mysql:5.5 3 | environment: 4 | - MYSQL_USER=unifiedpush 5 | - MYSQL_PASSWORD=unifiedpush 6 | - MYSQL_DATABASE=unifiedpush 7 | - MYSQL_ROOT_PASSWORD=supersecret 8 | ports: 9 | - 4306:3306 10 | keycloakDB: 11 | image: mysql:5.5 12 | environment: 13 | - MYSQL_USER=unifiedpush 14 | - MYSQL_PASSWORD=unifiedpush 15 | - MYSQL_DATABASE=keycloak 16 | - MYSQL_ROOT_PASSWORD=supersecret 17 | ports: 18 | - 4406:3306 19 | unifiedpushserver: 20 | image: aerogear/unifiedpush-wildfly-dev 21 | links: 22 | - unifiedpushDB:unifiedpush 23 | - keycloakDB:keycloak 24 | ports: 25 | - 8443:8443 -------------------------------------------------------------------------------- /docker-compose/ups-master/docker-compose-v3x.yaml: -------------------------------------------------------------------------------- 1 | version: "3.2" 2 | 3 | services: 4 | unifiedpushDB: 5 | image: mysql:5.5 6 | environment: 7 | MYSQL_USER: ${MYSQL_USER} 8 | MYSQL_PASSWORD: ${MYSQL_PASSWORD} 9 | MYSQL_DATABASE: ${MYSQL_DATABASE_UNIFIEDPUSH} 10 | MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} 11 | ports: 12 | - 4306:3306 13 | keycloakDB: 14 | image: mysql:5.5 15 | environment: 16 | MYSQL_USER: ${MYSQL_USER} 17 | MYSQL_PASSWORD: ${MYSQL_PASSWORD} 18 | MYSQL_DATABASE: ${MYSQL_DATABASE_KEYCLOAK} 19 | MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} 20 | ports: 21 | - 4406:3306 22 | unifiedpushserver: 23 | image: aerogear/unifiedpush-wildfly-dev 24 | environment: 25 | UNIFIEDPUSH_PORT_3306_TCP_ADDR: ${MYSQL_ADDR_UNIFIEDPUSH} 26 | UNIFIEDPUSH_ENV_MYSQL_USER: ${MYSQL_USER} 27 | UNIFIEDPUSH_ENV_MYSQL_PASSWORD: ${MYSQL_PASSWORD} 28 | UNIFIEDPUSH_PORT_3306_TCP_PORT: ${MYSQL_PORT_3306_TCP_PORT} 29 | UNIFIEDPUSH_ENV_MYSQL_DATABASE: ${MYSQL_DATABASE_UNIFIEDPUSH} 30 | KEYCLOAK_PORT_3306_TCP_ADDR: ${MYSQL_ADDR_KEYCLOAK} 31 | KEYCLOAK_ENV_MYSQL_USER: ${MYSQL_USER} 32 | KEYCLOAK_ENV_MYSQL_PASSWORD: ${MYSQL_PASSWORD} 33 | KEYCLOAK_PORT_3306_TCP_PORT: ${MYSQL_PORT_3306_TCP_PORT} 34 | KEYCLOAK_ENV_MYSQL_DATABASE: ${MYSQL_DATABASE_KEYCLOAK} 35 | links: 36 | - unifiedpushDB:unifiedpush 37 | - keycloakDB:keycloak 38 | ports: 39 | - 8443:8443 -------------------------------------------------------------------------------- /integration-tests/src/test/resources/development.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aerobase/unifiedpush-server/43430e1c3abaf62b331cbbeb6dd8036b81f3ca8a/integration-tests/src/test/resources/development.p12 -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/AbstractManagementEndpoint.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.jboss.aerogear.unifiedpush.rest; 19 | 20 | import javax.inject.Inject; 21 | 22 | import org.jboss.aerogear.unifiedpush.service.PushSearchService; 23 | 24 | /** 25 | * Base class for all management RESTful endpoints. Offers hooks for common 26 | * features like SearchManager. SearchManager is a prototype bean, therefore 27 | * extend this class only for management related RESTfull. 28 | */ 29 | public abstract class AbstractManagementEndpoint extends AbstractBaseEndpoint { 30 | 31 | @Inject 32 | private SearchManager searchManager; 33 | 34 | /** 35 | * offers PushSearchService to subclasses 36 | * 37 | * @return the push search service 38 | */ 39 | protected PushSearchService getSearch() { 40 | return searchManager.getSearchService(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/EmptyJSON.java: -------------------------------------------------------------------------------- 1 | /* 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.rest; 18 | 19 | /** 20 | * JSON with empty body. 21 | */ 22 | public final class EmptyJSON { 23 | 24 | public static final EmptyJSON OBJECT = new EmptyJSON(); 25 | public static final String STRING = "{}"; 26 | 27 | private EmptyJSON() {} 28 | } 29 | -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/HeartbeatEndpoint.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.ws.rs.GET; 5 | import javax.ws.rs.OPTIONS; 6 | import javax.ws.rs.Path; 7 | import javax.ws.rs.Produces; 8 | import javax.ws.rs.core.Context; 9 | import javax.ws.rs.core.HttpHeaders; 10 | import javax.ws.rs.core.MediaType; 11 | import javax.ws.rs.core.Response; 12 | 13 | import org.springframework.stereotype.Controller; 14 | 15 | import com.datastax.driver.core.utils.UUIDs; 16 | import com.qmino.miredot.annotations.ReturnType; 17 | 18 | @Controller 19 | @Path("/heartbeat") 20 | public class HeartbeatEndpoint extends AbstractBaseEndpoint { 21 | 22 | @OPTIONS 23 | @ReturnType("java.lang.Void") 24 | public Response crossOriginForApplication(@Context HttpHeaders headers) { 25 | return appendPreflightResponseHeaders(headers, Response.ok()).build(); 26 | } 27 | 28 | /** 29 | * Hartbeat Endpoint 30 | * 31 | * @return Hartbeat in form of time-based UUID. 32 | * @statuscode 200 Successful response for your request 33 | */ 34 | @GET 35 | @Produces(MediaType.APPLICATION_JSON) 36 | @ReturnType("java.lang.String") 37 | public Response hartbeat(@Context HttpServletRequest request) { 38 | return appendAllowOriginHeader(Response.ok().entity(quote(UUIDs.timeBased().toString())), request); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/PasswordContainer.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | public class PasswordContainer{ 6 | private String currentPassword; 7 | private String newPassword; 8 | 9 | public PasswordContainer() { 10 | super(); 11 | } 12 | 13 | public PasswordContainer(String currentPassword, String newPassword) { 14 | this.currentPassword = currentPassword; 15 | this.newPassword = newPassword; 16 | } 17 | 18 | public String getCurrentPassword() { 19 | return currentPassword; 20 | } 21 | 22 | public void setCurrentPassword(String currentPassword) { 23 | this.currentPassword = currentPassword; 24 | } 25 | 26 | public String getNewPassword() { 27 | return newPassword; 28 | } 29 | 30 | public void setNewPassword(String currentPassword) { 31 | this.newPassword = currentPassword; 32 | } 33 | 34 | public boolean isDataValid(){ 35 | return this != null && StringUtils.isNotBlank(this.currentPassword) && StringUtils.isNotBlank(this.newPassword); 36 | } 37 | } -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/RestApplication.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http:www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.rest; 18 | 19 | import javax.ws.rs.ApplicationPath; 20 | import javax.ws.rs.core.Application; 21 | 22 | /** 23 | * The JAX-RS {@link Application} representing the base entry point for all 24 | * RESTful HTTP requests. 25 | */ 26 | @ApplicationPath("/rest") 27 | public class RestApplication extends Application { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/WebConfig.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest; 2 | 3 | import javax.validation.Validator; 4 | 5 | import org.jboss.aerogear.unifiedpush.message.SenderConfig; 6 | import org.jboss.aerogear.unifiedpush.rest.registry.applications.BootstrapEndpoint; 7 | import org.jboss.aerogear.unifiedpush.spring.ServiceConfig; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.ComponentScan; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.context.annotation.Import; 12 | import org.springframework.context.support.ResourceBundleMessageSource; 13 | import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; 14 | 15 | @Configuration 16 | @Import({ ServiceConfig.class, SenderConfig.class }) 17 | @ComponentScan(basePackageClasses = { WebConfig.class, BootstrapEndpoint.class }) 18 | public class WebConfig { 19 | 20 | @Bean 21 | public Validator localValidatorFactoryBean() { 22 | return new LocalValidatorFactoryBean(); 23 | } 24 | 25 | @Bean 26 | public ResourceBundleMessageSource messageSource() { 27 | ResourceBundleMessageSource source = new ResourceBundleMessageSource(); 28 | source.setBasename("i18n/messages"); 29 | source.setUseCodeAsDefaultMessage(true); 30 | return source; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/annotations/PATCH.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.rest.annotations; 18 | 19 | import javax.ws.rs.HttpMethod; 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | /** 26 | * Indicates that the annotated method responds to HTTP PATCH requests 27 | */ 28 | @Target(ElementType.METHOD) 29 | @Retention(RetentionPolicy.RUNTIME) 30 | @HttpMethod("PATCH") 31 | public @interface PATCH { 32 | } 33 | -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/documents/DocumentList.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest.documents; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.jboss.aerogear.unifiedpush.api.document.IDocumentList; 7 | import org.jboss.aerogear.unifiedpush.cassandra.dao.model.parser.JsonDocumentContent; 8 | 9 | import com.fasterxml.jackson.annotation.JsonProperty; 10 | 11 | public final class DocumentList implements IDocumentList { 12 | private final List docs; 13 | private final List ignoredIds; 14 | 15 | public DocumentList() { 16 | super(); 17 | this.ignoredIds = new ArrayList(); 18 | this.docs = new ArrayList(); 19 | } 20 | 21 | @Override 22 | @JsonProperty 23 | public List getDocuments() { 24 | return docs; 25 | } 26 | 27 | @Override 28 | @JsonProperty(required = false) 29 | public List getIgnoredIds() { 30 | return ignoredIds; 31 | } 32 | 33 | public void ignore(String uuid) { 34 | ignoredIds.add(uuid); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/registry/installations/ImporterForm.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.rest.registry.installations; 18 | 19 | import javax.ws.rs.FormParam; 20 | 21 | /** 22 | * Helper class to read values from the multipart request 23 | * that is performed when uploading a JSON file for device import. 24 | */ 25 | public class ImporterForm { 26 | 27 | private byte[] jsonFile; 28 | 29 | /** 30 | * Reads the uploaded JSON file from the multipart importer request. 31 | * 32 | * @param jsonFile the json file content 33 | */ 34 | @FormParam("file") 35 | public void setJsonFile(byte[] jsonFile) { 36 | this.jsonFile = jsonFile; 37 | } 38 | 39 | public byte[] getJsonFile() { 40 | return jsonFile; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/util/CommonUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.rest.util; 18 | 19 | public class CommonUtils { 20 | 21 | private CommonUtils() { 22 | // no-op 23 | } 24 | 25 | /** 26 | * Verify if the string sorting matches with asc or desc 27 | * Returns FALSE when sorting query value matches desc, otherwise it returns TRUE. 28 | * 29 | * @param sorting the sorting value from the http header 30 | * @return false for desc or true for as 31 | */ 32 | public static Boolean isAscendingOrder(String sorting) { 33 | return "desc".equalsIgnoreCase(sorting) ? Boolean.FALSE : Boolean.TRUE; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /jaxrs/src/main/java/org/jboss/aerogear/unifiedpush/rest/util/PushAppAuthHelper.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest.util; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | 5 | import org.jboss.aerogear.unifiedpush.api.PushApplication; 6 | import org.jboss.aerogear.unifiedpush.service.PushApplicationService; 7 | 8 | public class PushAppAuthHelper { 9 | 10 | /** 11 | * returns application if the masterSecret is valid for the request PushApplicationEntity 12 | */ 13 | public static PushApplication loadPushApplicationWhenAuthorized(HttpServletRequest request, PushApplicationService pushApplicationService) { 14 | // extract the pushApplicationID and its secret from the HTTP Basic header: 15 | String[] credentials = HttpBasicHelper.extractUsernameAndPasswordFromBasicHeader(request); 16 | String pushApplicationID = credentials[0]; 17 | String secret = credentials[1]; 18 | 19 | final PushApplication pushApplication = pushApplicationService.findByPushApplicationID(pushApplicationID); 20 | if (pushApplication != null && pushApplication.getMasterSecret().equals(secret)) { 21 | return pushApplication; 22 | } 23 | 24 | // unauthorized... 25 | return null; 26 | } 27 | } -------------------------------------------------------------------------------- /jaxrs/src/main/resources/i18n/messages.properties: -------------------------------------------------------------------------------- 1 | org.jboss.aerogear.unifiedpush.api.pushapplication.unique.name=Application name ''{0}'' already exists -------------------------------------------------------------------------------- /jaxrs/src/main/resources/rest/sender/100.json: -------------------------------------------------------------------------------- 1 | { 2 | "operations": [ 3 | { 4 | "op": "add", 5 | "path": "/criteria", 6 | "value": {} 7 | }, 8 | { 9 | "op": "add", 10 | "path": "/config", 11 | "value": {} 12 | }, 13 | { 14 | "op": "add", 15 | "path": "/message/user-data", 16 | "value": {} 17 | }, 18 | { 19 | "op": "add", 20 | "path": "/message/apns", 21 | "value": {} 22 | }, 23 | { 24 | "op": "move", 25 | "from": "/message/action-category", 26 | "path": "/message/apns/action-category" 27 | }, 28 | { 29 | "op": "move", 30 | "from": "/message/content-available", 31 | "path": "/message/apns/content-available" 32 | }, 33 | { 34 | "op": "move", 35 | "from": "/alias", 36 | "path": "/criteria/alias" 37 | }, 38 | { 39 | "op": "move", 40 | "from": "/deviceType", 41 | "path": "/criteria/deviceType" 42 | }, 43 | { 44 | "op": "move", 45 | "from": "/categories", 46 | "path": "/criteria/categories" 47 | }, 48 | { 49 | "op": "move", 50 | "from": "/variants", 51 | "path": "/criteria/variants" 52 | }, 53 | { 54 | "op": "move", 55 | "from": "/ttl", 56 | "path": "/config/ttl" 57 | }, 58 | { 59 | "op": "move", 60 | "from": "/simple-push", 61 | "path": "/message/simple-push" 62 | } 63 | ], 64 | "dynamicTransformer": "UserParams" 65 | } -------------------------------------------------------------------------------- /jaxrs/src/test/filtered-resources/default.properties: -------------------------------------------------------------------------------- 1 | aerogear.config.verification.enable_verification=false 2 | aerogear.config.verification.impl.class=org.jboss.aerogear.unifiedpush.service.sms.ClickatellSMSSender 3 | 4 | aerogear.config.oauth2.enable=false 5 | aerogear.config.oauth2.admin.username=admin 6 | aerogear.config.oauth2.admin.password=password 7 | 8 | aerogear.config.oauth2.keycloak.url=http://localhost/auth 9 | aerogear.config.oauth2.ups.admin.client=admin-cli 10 | aerogear.config.oauth2.ups.realm.name=master 11 | aerogear.config.oauth2.enforce.rooturl.protocol=https 12 | aerogear.config.oauth2.enforce.rooturl.domain= 13 | 14 | aerogear.config.cassandra.consistencylevel=ONE 15 | aerogear.config.cassandra.keyspace=unifiedpush_server 16 | aerogear.config.cassandra.contactpoints=127.0.0.1 17 | aerogear.config.cassandra.port=9142 18 | aerogear.config.cassandra.rpc_port=9171 19 | aerogear.config.cassandra.storage_port=7010 20 | aerogear.config.cassandra.ssl_storage_port=7011 21 | aerogear.config.cassandra.cql.init.timeout=60000 -------------------------------------------------------------------------------- /jaxrs/src/test/java/org/jboss/aerogear/unifiedpush/rest/HeartbeatEndpointTest.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import java.util.UUID; 6 | 7 | import org.junit.Test; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 10 | 11 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = { WebConfigTest.class }) 12 | public class HeartbeatEndpointTest extends RestEndpointTest { 13 | 14 | @Test 15 | public void testHeartbeatEndpoint() { 16 | String uuid = testTemplate.getForObject(getRestFullPath() + "/heartbeat", String.class); 17 | 18 | assertTrue(uuid != null && UUID.fromString(uuid.replaceAll("\"", "")).toString() != null); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /jaxrs/src/test/java/org/jboss/aerogear/unifiedpush/rest/LoggedIn.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target({ElementType.FIELD, ElementType.METHOD}) 10 | public @interface LoggedIn { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /jaxrs/src/test/java/org/jboss/aerogear/unifiedpush/rest/RandomPortTests.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest; 2 | 3 | import static org.hamcrest.Matchers.not; 4 | import static org.junit.Assert.assertThat; 5 | 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.boot.context.embedded.LocalServerPort; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = { WebConfigTest.class }) 15 | public class RandomPortTests { 16 | 17 | @LocalServerPort 18 | protected int localPort; 19 | 20 | @Test 21 | public void getPort() { 22 | assertThat("Should get a random port greater than zero!", localPort, not(8080)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /jaxrs/src/test/java/org/jboss/aerogear/unifiedpush/rest/RestEndpointTest.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest; 2 | 3 | import org.jboss.aerogear.unifiedpush.service.AbstractCassandraServiceTest; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.boot.context.embedded.LocalServerPort; 6 | import org.springframework.boot.test.web.client.TestRestTemplate; 7 | 8 | public abstract class RestEndpointTest extends AbstractCassandraServiceTest implements IRestEndpointTest { 9 | 10 | @Autowired 11 | protected TestRestTemplate testTemplate; 12 | @LocalServerPort 13 | private int port; 14 | 15 | protected String getRestFullPath() { 16 | return "http://localhost:" + port + "/" + RESOURCE_PREFIX; 17 | } 18 | 19 | protected void specificSetup(){ 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /jaxrs/src/test/java/org/jboss/aerogear/unifiedpush/rest/RestNoRealtimedbTest.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest; 2 | 3 | import org.jboss.aerogear.unifiedpush.service.AbstractNoCassandraServiceTest; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.boot.context.embedded.LocalServerPort; 6 | import org.springframework.boot.test.web.client.TestRestTemplate; 7 | 8 | public abstract class RestNoRealtimedbTest extends AbstractNoCassandraServiceTest implements IRestEndpointTest { 9 | @Autowired 10 | protected TestRestTemplate testTemplate; 11 | @LocalServerPort 12 | private int port; 13 | 14 | protected String getRestFullPath() { 15 | return "http://localhost:" + port + "/" + RESOURCE_PREFIX; 16 | } 17 | 18 | protected void specificSetup(){ 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /jaxrs/src/test/java/org/jboss/aerogear/unifiedpush/rest/documents/DocumentInstallationWrapper.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest.documents; 2 | 3 | import java.util.UUID; 4 | 5 | import javax.ws.rs.core.MediaType; 6 | 7 | import org.jboss.aerogear.unifiedpush.api.Installation; 8 | import org.jboss.aerogear.unifiedpush.api.document.IDocument; 9 | 10 | import com.fasterxml.jackson.annotation.JsonIgnore; 11 | 12 | public class DocumentInstallationWrapper implements IDocument { 13 | 14 | private Installation content; 15 | 16 | public DocumentInstallationWrapper(Installation content) { 17 | super(); 18 | this.content = content; 19 | } 20 | 21 | @Override 22 | @JsonIgnore 23 | public String getKey() { 24 | return null; 25 | } 26 | 27 | @Override 28 | public void setKey(String key) { 29 | 30 | } 31 | 32 | @Override 33 | public Installation getContent() { 34 | return content; 35 | } 36 | 37 | @Override 38 | public void setContent(Installation content) { 39 | this.content = content; 40 | } 41 | 42 | @Override 43 | public String getContentType() { 44 | return MediaType.APPLICATION_JSON; 45 | } 46 | 47 | @Override 48 | public void setContentType(String contentType) { 49 | 50 | } 51 | 52 | @Override 53 | public String getDocumentId() { 54 | return UUID.randomUUID().toString(); 55 | } 56 | 57 | @Override 58 | public void setDocumentId(String documentId) { 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /jaxrs/src/test/java/org/jboss/aerogear/unifiedpush/rest/util/Authenticator.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.rest.util; 2 | 3 | import java.io.IOException; 4 | import java.io.UnsupportedEncodingException; 5 | 6 | import javax.ws.rs.client.ClientRequestContext; 7 | import javax.ws.rs.client.ClientRequestFilter; 8 | import javax.ws.rs.core.MultivaluedMap; 9 | import javax.xml.bind.DatatypeConverter; 10 | 11 | public class Authenticator implements ClientRequestFilter { 12 | 13 | private String user; 14 | private String password; 15 | 16 | public Authenticator(String user, String password) { 17 | this.user = user; 18 | this.password = password; 19 | } 20 | 21 | @Override 22 | public void filter(ClientRequestContext requestContext) throws IOException { 23 | MultivaluedMap headers = requestContext.getHeaders(); 24 | final String basicAuthentication = getBasicAuthentication(); 25 | headers.add("Authorization", basicAuthentication); 26 | 27 | } 28 | 29 | private String getBasicAuthentication() { 30 | String token = this.user + ":" + this.password; 31 | try { 32 | return "Basic " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8")); 33 | } catch (UnsupportedEncodingException ex) { 34 | throw new IllegalStateException("Cannot encode with UTF-8", ex); 35 | } 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /jaxrs/src/test/java/org/jboss/aerogear/unifiedpush/rest/util/CommonUtilsTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.rest.util; 18 | 19 | import org.junit.Test; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | import static org.jboss.aerogear.unifiedpush.rest.util.CommonUtils.isAscendingOrder; 23 | 24 | public class CommonUtilsTest { 25 | 26 | @Test 27 | public void verifyAscendingOrderFromNullValue() { 28 | assertThat(isAscendingOrder(null)).isTrue(); 29 | } 30 | 31 | @Test 32 | public void verfiyAscendingOrderFromDescValue() { 33 | assertThat(isAscendingOrder("deSc")).isFalse(); 34 | assertThat(isAscendingOrder("desc")).isFalse(); 35 | assertThat(isAscendingOrder("DESC")).isFalse(); 36 | } 37 | 38 | @Test 39 | public void verifyAscendingOrderFromAscValue() { 40 | assertThat(isAscendingOrder("foo")).isTrue(); 41 | assertThat(isAscendingOrder("AsC")).isTrue(); 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /jaxrs/src/test/resources/META-INF/db.properties: -------------------------------------------------------------------------------- 1 | # H2 connection string 2 | jdbcUrl=jdbc:h2:mem:unifiedpush;LOCK_TIMEOUT=10000 3 | 4 | dataSource.dataSource=true 5 | dataSource.prepStmtCacheSize=250 6 | dataSource.prepStmtCacheSqlLimit=2048 7 | dataSource.useServerPrepStmts=true 8 | 9 | # Maximum number of JDBC connections in the pool. Hibernate default: 100 10 | maximumPoolSize=100 11 | # Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire. Default: 300 12 | idleTimeout=300 -------------------------------------------------------------------------------- /jaxrs/src/test/resources/META-INF/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.dialect=org.hibernate.dialect.H2Dialect 2 | hibernate.hbm2ddl.import_files=META-INF/test-data.sql 3 | hibernate.hbm2ddl.auto=create 4 | hibernate.show_sql=false 5 | hibernate.format_sql=false 6 | hibernate.transaction.flush_before_completion=true 7 | hibernate.id.new_generator_mappings=true -------------------------------------------------------------------------------- /jaxrs/src/test/resources/META-INF/test-data.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- H2 database query 3 | -- 4 | 5 | INSERT INTO push_application VALUES ('711c8b98-9c2c-4d94-abe7-ecff7145c015', NULL, 'admin', '1f73558f-d01b-48d7-9f6a-fc5d0ec6da51', 'DEFAULT', '7385c294-2003-4abf-83f6-29a27415326b'); 6 | 7 | INSERT INTO variant VALUES ('ios', '5ede4a1b-0277-4467-992c-02a7b307e555', NULL, 'admin', 'DEFAULT', '088a814a-ff2b-4acf-9091-5bcd0ccece16', 1, 'd3f54c25-c3ce-4999-b7a8-27dc9bb01364', '711c8b98-9c2c-4d94-abe7-ecff7145c015'); 8 | INSERT INTO variant VALUES ('android', 'da168ba1-105a-4ba5-a17f-46c7ea2a32e4', NULL, 'admin', 'DEFAULT', '20aba35f-e472-4958-9f8f-f55f73e2e012', 0, '55b2c428-7102-43f7-96c0-96b5c7ba8dcc', '711c8b98-9c2c-4d94-abe7-ecff7145c015'); 9 | 10 | INSERT INTO ios_variant VALUES ('DEFAULT', 'DEFAULT', false, '5ede4a1b-0277-4467-992c-02a7b307e555'); 11 | INSERT INTO android_variant VALUES ('DEFAULT', 'DEFAULT', 'da168ba1-105a-4ba5-a17f-46c7ea2a32e4'); 12 | -------------------------------------------------------------------------------- /jaxrs/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=0 -------------------------------------------------------------------------------- /jaxrs/src/test/resources/cert/certificate.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aerobase/unifiedpush-server/43430e1c3abaf62b331cbbeb6dd8036b81f3ca8a/jaxrs/src/test/resources/cert/certificate.p12 -------------------------------------------------------------------------------- /jaxrs/src/test/resources/health-format.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "crit", 3 | "details": [ 4 | { 5 | "description": "db status", 6 | "result": "couldn't connect", 7 | "runtime": 111, 8 | "test_status": "crit" 9 | } 10 | ], 11 | "summary": "There is 1 error found" 12 | } -------------------------------------------------------------------------------- /jaxrs/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /migrator/liquibase-mysql-comparison.properties: -------------------------------------------------------------------------------- 1 | url=jdbc:mysql://localhost:6306/ups_stable 2 | driver=com.mysql.jdbc.Driver 3 | username=unifiedpush 4 | password=unifiedpush 5 | changeLogFile=liquibase/master.xml 6 | referenceUrl=jdbc:mysql://localhost:3306/ups_master 7 | referenceUsername=unifiedpush 8 | referencePassword=unifiedpush -------------------------------------------------------------------------------- /migrator/liquibase-mysql-example.properties: -------------------------------------------------------------------------------- 1 | url=jdbc:mysql://localhost:3306/unifiedpush100li 2 | driver=com.mysql.jdbc.Driver 3 | username=unifiedpush 4 | password=unifiedpush 5 | changeLogFile=liquibase/master.xml -------------------------------------------------------------------------------- /migrator/liquibase-pgsql-comparison.properties: -------------------------------------------------------------------------------- 1 | url=jdbc:postgresql://localhost:5432/ups_stable 2 | driver=org.postgresql.Driver 3 | username=unifiedpush 4 | password=unifiedpush 5 | changeLogFile=liquibase/master.xml 6 | referenceUrl=jdbc:postgresql://localhost:5432/ups_master 7 | referenceUsername=unifiedpush 8 | referencePassword=unifiedpush -------------------------------------------------------------------------------- /migrator/liquibase-postgresql-example.properties: -------------------------------------------------------------------------------- 1 | url=jdbc:postgresql://localhost:5432/ups_dev100li 2 | driver=org.postgresql.Driver 3 | username=unifiedpush 4 | password=unifiedpush 5 | changeLogFile=liquibase/master.xml -------------------------------------------------------------------------------- /migrator/src/main/resources/liquibase/1.0.0.Final/releasechanges.xml: -------------------------------------------------------------------------------- 1 | 19 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /migrator/src/main/resources/liquibase/1.0.2/releasechanges.xml: -------------------------------------------------------------------------------- 1 | 19 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /migrator/src/main/resources/liquibase/1.0.3/releasechanges.xml: -------------------------------------------------------------------------------- 1 | 19 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /migrator/src/main/resources/liquibase/1.1.0-Final/2015-07-09-drop-chromepackagedapp-variant.xml: -------------------------------------------------------------------------------- 1 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /migrator/src/main/resources/liquibase/1.2.0/releasechanges.xml: -------------------------------------------------------------------------------- 1 | 19 | 24 | 25 | -------------------------------------------------------------------------------- /migrator/src/main/resources/liquibase/master.xml: -------------------------------------------------------------------------------- 1 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /migrator/src/main/scripts/recreate_db.sql: -------------------------------------------------------------------------------- 1 | drop database if exists ups_master; 2 | create database ups_master default character set = "UTF8" default collate = "utf8_general_ci"; 3 | GRANT SELECT,INSERT,UPDATE,ALTER,DELETE,CREATE,DROP,INDEX ON ups_master.* TO 'unifiedpush'@'localhost'; -------------------------------------------------------------------------------- /migrator/src/main/scripts/recreate_stable_db.sql: -------------------------------------------------------------------------------- 1 | drop database if exists ups_stable; 2 | create database ups_stable default character set = "UTF8" default collate = "utf8_general_ci"; 3 | GRANT SELECT,INSERT,UPDATE,ALTER,DELETE,CREATE,DROP,INDEX ON ups_stable.* TO 'unifiedpush'@'localhost'; -------------------------------------------------------------------------------- /migrator/src/main/scripts/run-mysql: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mvn clean package \ 3 | && cd target && unzip unifiedpush-migrator-1.1.0.Fina-dist.zip \ 4 | && cd unifiedpush-migrator-1.1.0.Final/ \ 5 | && cp ../../liquibase-mysql-example.properties liquibase.properties \ 6 | && mkdir liquibase && bin/ups-migrator --logLevel=INFO update 7 | -------------------------------------------------------------------------------- /migrator/src/main/scripts/run-pgsql: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mvn clean package \ 3 | && cd target && unzip unifiedpush-migrator-1.1.0.Final-dist.zip \ 4 | && cd unifiedpush-migrator-1.1.0.Final/ \ 5 | && cp ../../liquibase-pgsql-comparison.properties liquibase.properties \ 6 | && mkdir liquibase && bin/ups-migrator --logLevel=INFO update 7 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/Alias.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.api; 2 | 3 | import java.util.UUID; 4 | 5 | public class Alias { 6 | private UUID id; 7 | private UUID pushApplicationId; 8 | private String email; 9 | private String other; 10 | 11 | public Alias() { 12 | } 13 | 14 | private Alias(UUID id) { 15 | super(); 16 | this.id = id; 17 | } 18 | 19 | public Alias(UUID pushApplicationId, UUID id) { 20 | this(id); 21 | this.pushApplicationId = pushApplicationId; 22 | } 23 | 24 | public Alias(UUID pushApplicationId, UUID id, String email) { 25 | this(pushApplicationId, id); 26 | this.email = email; 27 | } 28 | 29 | public Alias(UUID pushApplicationId, UUID id, String email, String other) { 30 | this(pushApplicationId, id); 31 | this.email = email; 32 | this.other = other; 33 | } 34 | 35 | public UUID getId() { 36 | return this.id; 37 | } 38 | 39 | public void setId(UUID id) { 40 | this.id = id; 41 | } 42 | 43 | public UUID getPushApplicationId() { 44 | return pushApplicationId; 45 | } 46 | 47 | public void setPushApplicationId(UUID pushApplicationId) { 48 | this.pushApplicationId = pushApplicationId; 49 | } 50 | 51 | public String getEmail() { 52 | return email; 53 | } 54 | 55 | public void setEmail(String email) { 56 | this.email = email; 57 | } 58 | 59 | public String getOther() { 60 | return other; 61 | } 62 | 63 | public void setOther(String other) { 64 | this.other = other; 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | return "Alias [id=" + id + ", pushApplicationId=" + pushApplicationId + ", email=" + email + ", other=" + other 70 | + "]"; 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/BaseModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.api; 18 | 19 | import java.io.Serializable; 20 | import java.util.UUID; 21 | 22 | public abstract class BaseModel implements Serializable { 23 | 24 | private static final long serialVersionUID = -4123402116687584512L; 25 | 26 | private String id = UUID.randomUUID().toString(); 27 | 28 | /** 29 | * Key identifying the model object in the underlying database (primary key) 30 | * 31 | * @param id value of the primary key 32 | */ 33 | public void setId(final String id) { 34 | this.id = id; 35 | } 36 | public String getId() { 37 | return this.id; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/IUser.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.api; 2 | 3 | public interface IUser { 4 | 5 | ID getKey(); 6 | 7 | void setKey(ID key); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/InstallationVerificationAttempt.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.api; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | public class InstallationVerificationAttempt { 6 | 7 | // Verification code 8 | private String code; 9 | // Device token 10 | private String deviceToken; 11 | // Indication to also activate oauth2 user 12 | private boolean oauth2 = false; 13 | 14 | public InstallationVerificationAttempt() { 15 | } 16 | 17 | public InstallationVerificationAttempt(String code, String deviceToken) { 18 | this.code = code; 19 | this.deviceToken = deviceToken; 20 | this.oauth2 = false; 21 | } 22 | 23 | public InstallationVerificationAttempt(String code, String deviceToken, boolean oauth2) { 24 | super(); 25 | this.code = code; 26 | this.deviceToken = deviceToken; 27 | this.oauth2 = oauth2; 28 | } 29 | 30 | public String getCode() { 31 | return this.code; 32 | } 33 | 34 | public void setCode(String code) { 35 | this.code = code; 36 | } 37 | 38 | public String getDeviceToken() { 39 | return this.deviceToken; 40 | } 41 | 42 | public void setDeviceToken(String deviceToken) { 43 | this.deviceToken = deviceToken; 44 | } 45 | 46 | @JsonProperty(required = false) 47 | public boolean isOauth2() { 48 | return oauth2; 49 | } 50 | 51 | public void setOauth2(boolean oauth2) { 52 | this.oauth2 = oauth2; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/SimplePushVariant.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.api; 18 | 19 | /** 20 | * The SimplePush variant class encapsulates SimplePush specific behavior. 21 | */ 22 | public class SimplePushVariant extends Variant { 23 | private static final long serialVersionUID = 9046963507735955449L; 24 | 25 | @Override 26 | public VariantType getType() { 27 | return VariantType.SIMPLE_PUSH; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/WindowsVariant.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.api; 18 | 19 | import com.fasterxml.jackson.annotation.JsonSubTypes; 20 | import com.fasterxml.jackson.annotation.JsonTypeInfo; 21 | import com.fasterxml.jackson.annotation.JsonTypeInfo.As; 22 | import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; 23 | 24 | @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "protocolType") 25 | @JsonSubTypes({ 26 | @JsonSubTypes.Type(value=WindowsWNSVariant.class, name="wns") 27 | }) 28 | public abstract class WindowsVariant extends Variant { 29 | 30 | private static final long serialVersionUID = 4116027822443177838L; 31 | } 32 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/document/IDocument.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.api.document; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | 5 | public interface IDocument { 6 | 7 | @JsonIgnore 8 | ID getKey(); 9 | 10 | void setKey(ID key); 11 | 12 | CT getContent(); 13 | 14 | void setContent(CT content); 15 | 16 | String getContentType(); 17 | 18 | void setContentType(String contentType); 19 | 20 | String getDocumentId(); 21 | 22 | void setDocumentId(String documentId); 23 | } 24 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/document/IDocumentList.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.api.document; 2 | 3 | import java.util.List; 4 | 5 | public interface IDocumentList, I> { 6 | List getDocuments(); 7 | 8 | List getIgnoredIds(); 9 | } 10 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/document/QueryOptions.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.api.document; 2 | 3 | public class QueryOptions { 4 | 5 | private Long fromDate; 6 | private Long toDate; 7 | private String id; 8 | private Integer limit; 9 | 10 | public QueryOptions() { 11 | 12 | } 13 | 14 | public QueryOptions(String id) { 15 | super(); 16 | this.id = id; 17 | } 18 | 19 | public QueryOptions(String id, int limit) { 20 | super(); 21 | this.id = id; 22 | this.limit = limit; 23 | } 24 | 25 | public QueryOptions(Long fromDate) { 26 | super(); 27 | this.fromDate = fromDate; 28 | } 29 | 30 | public QueryOptions(Long fromDate, Long toDate) { 31 | super(); 32 | this.fromDate = fromDate; 33 | this.toDate = toDate; 34 | } 35 | 36 | public QueryOptions(Long fromDate, Long toDate, String id, Integer limit) { 37 | super(); 38 | this.fromDate = fromDate; 39 | this.toDate = toDate; 40 | this.id = id; 41 | this.limit = limit; 42 | } 43 | 44 | public Long getFromDate() { 45 | return fromDate; 46 | } 47 | 48 | public void setFromDate(Long fromDate) { 49 | this.fromDate = fromDate; 50 | } 51 | 52 | public Long getToDate() { 53 | return toDate; 54 | } 55 | 56 | public void setToDate(Long toDate) { 57 | this.toDate = toDate; 58 | } 59 | 60 | public String getId() { 61 | return id; 62 | } 63 | 64 | public void setId(String id) { 65 | this.id = id; 66 | } 67 | 68 | public Integer getLimit() { 69 | return limit; 70 | } 71 | 72 | public void setLimit(Integer limit) { 73 | this.limit = limit; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/validation/AlwaysFalseValidator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.api.validation; 18 | 19 | import javax.validation.ConstraintValidator; 20 | import javax.validation.ConstraintValidatorContext; 21 | 22 | /** 23 | * Validator that will always validate for true 24 | */ 25 | public class AlwaysFalseValidator implements ConstraintValidator { 26 | 27 | @Override 28 | public void initialize(AlwaysTrueValidation validation) { 29 | } 30 | 31 | @Override 32 | public boolean isValid(String value, ConstraintValidatorContext context) { 33 | return false; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/validation/AlwaysTrueValidation.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.api.validation; 18 | 19 | import java.lang.annotation.Documented; 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | import javax.validation.Constraint; 26 | 27 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Constraint(validatedBy = AlwaysTrueValidator.class) 30 | @Documented 31 | public @interface AlwaysTrueValidation { 32 | 33 | } 34 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/validation/AlwaysTrueValidator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.api.validation; 18 | 19 | import javax.validation.ConstraintValidator; 20 | import javax.validation.ConstraintValidatorContext; 21 | 22 | /** 23 | * Validator that will always validate for true 24 | */ 25 | public class AlwaysTrueValidator implements ConstraintValidator { 26 | 27 | @Override 28 | public void initialize(AlwaysTrueValidation validation) { 29 | } 30 | 31 | @Override 32 | public boolean isValid(String value, ConstraintValidatorContext context) { 33 | return true; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/validation/DeviceTokenCheck.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.api.validation; 18 | 19 | import javax.validation.Constraint; 20 | import javax.validation.Payload; 21 | import java.lang.annotation.Documented; 22 | import java.lang.annotation.ElementType; 23 | import java.lang.annotation.Retention; 24 | import java.lang.annotation.RetentionPolicy; 25 | import java.lang.annotation.Target; 26 | 27 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Constraint(validatedBy = DeviceTokenValidator.class) 30 | @Documented 31 | public @interface DeviceTokenCheck { 32 | 33 | String message() default "{org.jboss.aerogear.unifiedpush.model.constraints.devicetoken}"; 34 | 35 | Class[] groups() default {}; 36 | 37 | Class[] payload() default {}; 38 | } 39 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/api/verification/VerificationPublisher.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.api.verification; 2 | 3 | import java.util.Properties; 4 | 5 | import org.slf4j.Logger; 6 | 7 | /** 8 | * Implementation of this class are responsible for sending SMS messages. 9 | */ 10 | public interface VerificationPublisher { 11 | 12 | /** 13 | * Sends the message to number. 14 | * @param phoneNumber number to send to 15 | * @param code OTP verification code. 16 | * @param properties any additional properties required to configure this sms sender 17 | */ 18 | void send(String phoneNumber, String code, Properties properties); 19 | 20 | /** 21 | * Indicates rather next validation in chain should be validated. 22 | */ 23 | default boolean chain() {return true;}; 24 | 25 | static void logError(Logger logger, String type, String hostname, String portnumb, String username, String password, String fromaddr, 26 | String toaddres, String subjectt, Exception e) { 27 | 28 | StringBuilder builder = new StringBuilder(); 29 | builder.append("Cannot send " + type + " message using"); 30 | builder.append(": hostname: ").append(hostname); 31 | builder.append(", portnumb: ").append(portnumb); 32 | builder.append(", username: ").append(username); 33 | builder.append(", password: ").append(password); 34 | builder.append(", fromaddr: ").append(fromaddr); 35 | builder.append(", toaddres: ").append(toaddres); 36 | 37 | logger.error(builder.toString(), e); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/dao/CategoryDao.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.dao; 18 | 19 | import org.jboss.aerogear.unifiedpush.api.Category; 20 | 21 | import java.util.List; 22 | 23 | public interface CategoryDao extends GenericBaseDao { 24 | 25 | List findByNames(List names); 26 | } 27 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/dao/GenericBaseDao.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.dao; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Generic base interface for different DAO layers 7 | * @param Object type 8 | * @param primary key 9 | */ 10 | public interface GenericBaseDao { 11 | 12 | O find(K id); 13 | 14 | List findAll(); 15 | 16 | void create(O o); 17 | 18 | void update(O o); 19 | 20 | void delete(O o); 21 | 22 | void flushAndClear(); 23 | 24 | void lock(O entity); 25 | } 26 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/dao/PageResult.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.dao; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Holds the result of a query plus the total number of rows 7 | * @param the type of the result 8 | */ 9 | public class PageResult { 10 | 11 | private final List resultList; 12 | private final A aggregate; 13 | 14 | public PageResult(List resultList, A aggregate) { 15 | this.resultList = resultList; 16 | this.aggregate = aggregate; 17 | } 18 | 19 | public List getResultList() { 20 | return resultList; 21 | } 22 | 23 | public A getAggregate() { 24 | return aggregate; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return "PageResult{" + 30 | "aggregate=" + aggregate + 31 | ", resultList=" + resultList + 32 | '}'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/dao/ResultStreamException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.dao; 18 | 19 | /** 20 | * Exception thrown when stream of results is failed to be read from underlying database 21 | */ 22 | public class ResultStreamException extends Exception { 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | public ResultStreamException() { 27 | super(); 28 | } 29 | 30 | public ResultStreamException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 31 | super(message, cause, enableSuppression, writableStackTrace); 32 | } 33 | 34 | public ResultStreamException(String message, Throwable cause) { 35 | super(message, cause); 36 | } 37 | 38 | public ResultStreamException(String message) { 39 | super(message); 40 | } 41 | 42 | public ResultStreamException(Throwable cause) { 43 | super(cause); 44 | } 45 | 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/dao/helper/InstallationAlias.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.dao.helper; 2 | 3 | public class InstallationAlias { 4 | private String id; 5 | private String alias; 6 | 7 | public InstallationAlias() { 8 | 9 | } 10 | 11 | public InstallationAlias(String id, String alias) { 12 | super(); 13 | this.id = id; 14 | this.alias = alias; 15 | } 16 | 17 | public String getId() { 18 | return id; 19 | } 20 | 21 | public void setId(String id) { 22 | this.id = id; 23 | } 24 | 25 | public String getAlias() { 26 | return alias; 27 | } 28 | 29 | public void setAlias(String alias) { 30 | this.alias = alias; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/dto/Count.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.dto; 18 | 19 | /** 20 | * DTO transferring counts 21 | */ 22 | public class Count { 23 | 24 | private final long count; 25 | 26 | public Count(Long count) { 27 | this.count = count; 28 | } 29 | 30 | public long getCount() { 31 | return count; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "Count [count=" + count + "]"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/dto/MessageMetrics.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.dto; 18 | 19 | /** 20 | * DTO transferring count together with number of receivers and app opened counter 21 | */ 22 | public class MessageMetrics { 23 | 24 | private final long count; 25 | private final long appOpenedCounter; 26 | 27 | public MessageMetrics(Long count, Long appOpenedCounter) { 28 | this.count = count; 29 | this.appOpenedCounter = (appOpenedCounter == null) ? 0 : appOpenedCounter; 30 | } 31 | 32 | public long getCount() { 33 | return count; 34 | } 35 | 36 | public long getAppOpenedCounter() { 37 | return appOpenedCounter; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return "MessageMetrics [count=" + count + ", appOpenedCounter=" + appOpenedCounter + "]"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/event/iOSVariantUpdateEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.event; 18 | 19 | import org.jboss.aerogear.unifiedpush.api.iOSVariant; 20 | 21 | /** 22 | * Fired when the iOS variant is updated to contain a new .p12 file, 23 | * therefore the update event is used to trigger a removal from the internal connection cache. 24 | */ 25 | public class iOSVariantUpdateEvent { 26 | 27 | private iOSVariant iOSVariant; 28 | 29 | public iOSVariantUpdateEvent(iOSVariant iOSVariant) { 30 | this.iOSVariant = iOSVariant; 31 | } 32 | 33 | public iOSVariant getiOSVariant() { 34 | return iOSVariant; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/utils/DateUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.utils; 18 | 19 | import java.util.Calendar; 20 | import java.util.Date; 21 | 22 | public final class DateUtils { 23 | 24 | private DateUtils() { 25 | // no-op 26 | } 27 | 28 | /** 29 | * Returns date in history: Today - the given number of days 30 | * 31 | * @param days number of days 32 | * 33 | * @return date object that lives n days in the past 34 | */ 35 | public static Date calculatePastDate(int days) { 36 | final Calendar cal = Calendar.getInstance(); 37 | cal.add(Calendar.DATE, -days); 38 | 39 | return cal.getTime(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /model/api/src/main/java/org/jboss/aerogear/unifiedpush/utils/UUIDToDate.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.utils; 2 | 3 | import java.util.UUID; 4 | 5 | public class UUIDToDate { 6 | // This method comes from Hector's TimeUUIDUtils class: 7 | // https://github.com/rantav/hector/blob/master/core/src/main/java/me/prettyprint/cassandra/utils/TimeUUIDUtils.java 8 | static final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L; 9 | 10 | public static long getTimeFromUUID(UUID uuid) { 11 | return (uuid.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH) / 10000; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /model/jpa/.gitignore: -------------------------------------------------------------------------------- 1 | derby.log 2 | -------------------------------------------------------------------------------- /model/jpa/src/main/java/org/jboss/aerogear/unifiedpush/jpa/dao/impl/JPACategoryDao.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.jpa.dao.impl; 18 | 19 | import org.jboss.aerogear.unifiedpush.api.Category; 20 | import org.jboss.aerogear.unifiedpush.dao.CategoryDao; 21 | import org.springframework.stereotype.Repository; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | @Repository 27 | public class JPACategoryDao extends JPABaseDao implements CategoryDao { 28 | 29 | @Override 30 | public List findByNames(List names) { 31 | List categoryList = new ArrayList<>(); 32 | if(!names.isEmpty()){ 33 | categoryList = entityManager.createQuery("select c from Category c where c.name in :names", Category.class) 34 | .setParameter("names", names).getResultList(); 35 | } 36 | return categoryList; 37 | } 38 | 39 | @Override 40 | public Class getType() { 41 | return Category.class; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /model/jpa/src/main/java/org/jboss/aerogear/unifiedpush/jpa/dao/impl/JPAHealthDao.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.jpa.dao.impl; 18 | 19 | import javax.inject.Inject; 20 | import javax.persistence.EntityManager; 21 | 22 | import org.springframework.stereotype.Repository; 23 | 24 | /** 25 | * Simple dao that checks if the database is available by running select 1 query. 26 | */ 27 | @Repository 28 | public class JPAHealthDao { 29 | @Inject 30 | private EntityManager entityManager; 31 | 32 | public boolean dbCheck() { 33 | return entityManager.createNativeQuery("SELECT 1").getResultList() != null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /model/jpa/src/main/resources/ValidationMessages.properties: -------------------------------------------------------------------------------- 1 | # 2 | # JBoss, Home of Professional Open Source 3 | # Copyright Red Hat, Inc., and individual contributors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | org.jboss.aerogear.unifiedpush.model.constraints.devicetoken=Device token is not valid for this device type -------------------------------------------------------------------------------- /model/jpa/src/main/resources/org/jboss/aerogear/unifiedpush/api/Category.hbm.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | category_seq 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /model/jpa/src/main/resources/org/jboss/aerogear/unifiedpush/api/VariantErrorStatus.hbm.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /model/jpa/src/test/java/org/jboss/aerogear/unifiedpush/utils/TestUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.utils; 18 | 19 | public final class TestUtils { 20 | 21 | private TestUtils() { 22 | // no-op 23 | } 24 | 25 | /** 26 | * Helper to generate long (String) values, based on the given argument 27 | */ 28 | public static String longString(int capacity) { 29 | final StringBuilder sb = new StringBuilder(capacity); 30 | for (int i = 0; i < capacity; i++) { 31 | sb.append("x"); 32 | } 33 | return sb.toString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /model/jpa/src/test/resources/AndroidVariant.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /model/jpa/src/test/resources/Categories.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 |
20 | id 21 | name 22 | 23 | 1 24 | cat1 25 | 26 | 27 | 2 28 | cat2 29 | 30 | 31 | 3 32 | cat3 33 | 34 |
35 | 36 | -------------------------------------------------------------------------------- /model/jpa/src/test/resources/META-INF/db.properties: -------------------------------------------------------------------------------- 1 | # H2 connection string 2 | jdbcUrl=jdbc:h2:mem:unifiedpush;INIT=CREATE SCHEMA IF NOT EXISTS SA\\;SET SCHEMA SA 3 | username=sa 4 | 5 | dataSource.dataSource=true 6 | dataSource.prepStmtCacheSize=250 7 | dataSource.prepStmtCacheSqlLimit=2048 8 | dataSource.useServerPrepStmts=true 9 | 10 | # Maximum number of JDBC connections in the pool. Hibernate default: 100 11 | maximumPoolSize=100 12 | # Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire. Default: 300 13 | idleTimeout=300 -------------------------------------------------------------------------------- /model/jpa/src/test/resources/META-INF/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.dialect=org.hibernate.dialect.H2Dialect 2 | hibernate.hbm2ddl.auto=create 3 | hibernate.show_sql=false 4 | hibernate.format_sql=false 5 | hibernate.transaction.flush_before_completion=true 6 | hibernate.id.new_generator_mappings=true -------------------------------------------------------------------------------- /model/jpa/src/test/resources/dbunit-express.properties: -------------------------------------------------------------------------------- 1 | dbunit-express.autoInitializeDb=false 2 | dbunit.connectionUrl=jdbc:h2:mem:unifiedpush;SCHEMA=SA -------------------------------------------------------------------------------- /model/jpa/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/RetryCassandraSessionFactoryBean.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.support.BeanDefinitionRegistry; 7 | import org.springframework.beans.factory.support.DefaultListableBeanFactory; 8 | import org.springframework.context.ApplicationContext; 9 | import org.springframework.data.cassandra.config.CassandraSessionFactoryBean; 10 | 11 | /** 12 | * Override CassandraSessionFactoryBean and retry connection X times. TODO - 13 | * Extract loop count and sleep interval to configuration. 14 | */ 15 | public class RetryCassandraSessionFactoryBean extends CassandraSessionFactoryBean { 16 | private final Logger logger = LoggerFactory.getLogger(RetryCassandraSessionFactoryBean.class); 17 | 18 | @Autowired 19 | private CassandraConfig config; 20 | 21 | @Autowired 22 | private ApplicationContext applicationCtx; 23 | 24 | @Override 25 | public void afterPropertiesSet() throws Exception { 26 | for (int i = 0; 1 < 20; i++) { 27 | try { 28 | super.afterPropertiesSet(); 29 | break; 30 | } catch (Exception e) { 31 | if (i == 20) 32 | throw e; 33 | logger.warn("Unable to connect to cassandra endpoints, retry " + (i + 1) + "/20"); 34 | 35 | // Destroy Singleton and recreate a new factory. 36 | BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) applicationCtx 37 | .getAutowireCapableBeanFactory(); 38 | ((DefaultListableBeanFactory) beanFactory).destroySingleton("cluster"); 39 | 40 | super.setCluster(config.cluster().getObject()); 41 | 42 | Thread.sleep(10000); 43 | } 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/AliasDao.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao; 2 | 3 | import java.util.List; 4 | import java.util.UUID; 5 | import java.util.stream.Stream; 6 | 7 | import org.jboss.aerogear.unifiedpush.api.Alias; 8 | import org.jboss.aerogear.unifiedpush.cassandra.dao.model.User; 9 | import org.springframework.cache.annotation.CacheEvict; 10 | import org.springframework.cache.annotation.Cacheable; 11 | 12 | import com.datastax.driver.core.Row; 13 | 14 | public interface AliasDao { 15 | public static final String CACHE_NAME = "aliases"; 16 | 17 | List create(Alias alias); 18 | 19 | List findAll(UUID pushApplicationId); 20 | 21 | @CacheEvict(value = CACHE_NAME, allEntries = true) 22 | void removeAll(UUID pushApplicationId); 23 | 24 | @CacheEvict(value = CACHE_NAME) 25 | void remove(UUID pushApplicationId, String alias); 26 | 27 | @Cacheable(value = CACHE_NAME, condition = "#pushApplicationId != null", unless = "#result == null") 28 | Alias findByAlias(UUID pushApplicationId, String alias); 29 | 30 | /** 31 | * Remove all aliases according to given parameters. All aliases are 32 | * manually evicted from cache. 33 | * 34 | * @param pushApplicationId 35 | * selected push application 36 | * @param userId 37 | * User in UUID v1 format 38 | */ 39 | void remove(UUID pushApplicationId, UUID userId); 40 | 41 | Stream findUserIds(UUID pushApplicationId); 42 | 43 | Alias findOne(UUID pushApplicationId, UUID userId); 44 | } 45 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/CacheConfig.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao; 2 | 3 | import java.util.Arrays; 4 | 5 | import org.springframework.cache.CacheManager; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | import org.springframework.cache.caffeine.CaffeineCacheManager; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | 11 | import com.github.benmanes.caffeine.cache.CaffeineSpec; 12 | 13 | @Configuration 14 | @EnableCaching 15 | public class CacheConfig { 16 | 17 | @Bean 18 | public CacheManager cacheManager() { 19 | CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager(); 20 | caffeineCacheManager.setCaffeineSpec(CaffeineSpec.parse("maximumSize=10000,expireAfterAccess=600s")); 21 | caffeineCacheManager.setCacheNames(Arrays.asList(DatabaseDao.CACHE_NAME, AliasDao.CACHE_NAME)); 22 | 23 | return caffeineCacheManager; 24 | } 25 | } -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/DatabaseDao.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao; 2 | 3 | import java.util.UUID; 4 | import java.util.stream.Stream; 5 | 6 | import org.jboss.aerogear.unifiedpush.cassandra.dao.model.Database; 7 | import org.jboss.aerogear.unifiedpush.cassandra.dao.model.DatabaseKey; 8 | import org.jboss.aerogear.unifiedpush.cassandra.dao.model.DatabaseQueryKey; 9 | import org.springframework.cache.annotation.Cacheable; 10 | import org.springframework.data.repository.CrudRepository; 11 | 12 | public interface DatabaseDao extends CrudRepository { 13 | public static final String CACHE_NAME = "databases"; 14 | 15 | @Cacheable(value = DatabaseDao.CACHE_NAME, unless = "#result == null") 16 | Database findOne(DatabaseQueryKey key); 17 | 18 | Stream find(UUID pushApplicationId); 19 | 20 | void create(Database database); 21 | 22 | void delete(Database database); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/DistinctUitils.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | import java.util.function.Function; 6 | import java.util.function.Predicate; 7 | 8 | public class DistinctUitils { 9 | public static Predicate distinctByKey(Function keyExtractor) { 10 | Map map = new ConcurrentHashMap<>(); 11 | return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/DocumentDao.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | import java.util.UUID; 6 | import java.util.stream.Stream; 7 | 8 | import org.jboss.aerogear.unifiedpush.api.Alias; 9 | import org.jboss.aerogear.unifiedpush.api.document.QueryOptions; 10 | import org.jboss.aerogear.unifiedpush.cassandra.dao.model.DocumentContent; 11 | 12 | public interface DocumentDao { 13 | 14 | DocumentContent create(DocumentContent document); 15 | 16 | void delete(UUID pushApplicationId); 17 | 18 | void delete(UUID pushApplicaitonId, Alias alias); 19 | 20 | void delete(T doc); 21 | 22 | Stream find(ID key, QueryOptions options); 23 | 24 | Optional findOne(ID key); 25 | 26 | DocumentContent findOne(ID key, String documentId); 27 | 28 | List findLatestForAliases(ID key, List aliases, String documentId); 29 | } 30 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/NullAlias.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao; 2 | 3 | import java.util.UUID; 4 | 5 | import org.jboss.aerogear.unifiedpush.api.Alias; 6 | import org.jboss.aerogear.unifiedpush.cassandra.dao.NullUUID; 7 | 8 | public class NullAlias { 9 | 10 | public static Alias getAlias(String pushApplicationId) { 11 | return new Alias(UUID.fromString(pushApplicationId), NullUUID.NULL.getUuid(), null); 12 | } 13 | 14 | public static Alias getAlias(UUID pushApplicationId) { 15 | return new Alias(pushApplicationId, NullUUID.NULL.getUuid(), null); 16 | } 17 | 18 | public static boolean isNullAlias(Alias alias) { 19 | return NullUUID.NULL.getUuid().equals(alias.getId()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/NullUUID.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao; 2 | 3 | import java.time.Instant; 4 | import java.util.UUID; 5 | 6 | import com.datastax.driver.core.utils.UUIDs; 7 | 8 | public enum NullUUID { 9 | 10 | NULL(UUIDs.startOf(Instant.EPOCH.toEpochMilli())); 11 | 12 | // Members 13 | private UUID uuid; 14 | 15 | // Constructor 16 | NullUUID(UUID uuid) { 17 | this.uuid = uuid; 18 | } 19 | 20 | // Getters 21 | public UUID getUuid() { 22 | return this.uuid; 23 | } 24 | } -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/impl/AliasAlreadyExists.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao.impl; 2 | 3 | import java.util.UUID; 4 | 5 | public class AliasAlreadyExists extends RuntimeException { 6 | private static final long serialVersionUID = 1874258278307431759L; 7 | 8 | public final String alias; 9 | public final UUID pushApplicationId; 10 | 11 | private AliasAlreadyExists(String alias, UUID pushApplicationId, String msg) { 12 | super(msg); 13 | this.alias = alias; 14 | this.pushApplicationId = pushApplicationId; 15 | } 16 | 17 | public AliasAlreadyExists(String alias, UUID pushApplicationId) { 18 | this(alias, pushApplicationId, 19 | String.format("Cannot add already existing alias \"%s\"", alias)); 20 | } 21 | 22 | public AliasAlreadyExists(String alias) { 23 | this(alias, null); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/model/Database.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao.model; 2 | 3 | import java.util.UUID; 4 | 5 | import javax.validation.constraints.NotNull; 6 | 7 | import org.springframework.data.cassandra.core.mapping.Column; 8 | import org.springframework.data.cassandra.core.mapping.PrimaryKey; 9 | import org.springframework.data.cassandra.core.mapping.Table; 10 | 11 | import com.fasterxml.jackson.annotation.JsonIgnore; 12 | 13 | @Table(value = "databases") 14 | public class Database { 15 | @NotNull 16 | @PrimaryKey 17 | @JsonIgnore 18 | private DatabaseKey key; 19 | 20 | @Column 21 | private String database; 22 | 23 | public Database() { 24 | } 25 | 26 | public Database(DatabaseQueryKey qkey) { 27 | super(); 28 | this.key = new DatabaseKey(qkey.getPushApplicationId()); 29 | this.database = qkey.getDatabase(); 30 | } 31 | 32 | public Database(UUID pushApplicationId, String database) { 33 | super(); 34 | this.key = new DatabaseKey(pushApplicationId); 35 | this.database = database; 36 | } 37 | 38 | public String getDatabase() { 39 | return database; 40 | } 41 | 42 | public void setDatabase(String database) { 43 | this.database = database; 44 | } 45 | 46 | public DatabaseKey getKey() { 47 | return key; 48 | } 49 | 50 | public void setKey(DatabaseKey key) { 51 | this.key = key; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/model/DatabaseKey.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import java.util.UUID; 6 | 7 | import org.springframework.data.cassandra.core.cql.Ordering; 8 | import org.springframework.data.cassandra.core.cql.PrimaryKeyType; 9 | import org.springframework.data.cassandra.core.mapping.PrimaryKeyClass; 10 | import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn; 11 | 12 | @PrimaryKeyClass 13 | public class DatabaseKey implements Serializable { 14 | private static final long serialVersionUID = -6419944724251681328L; 15 | 16 | @PrimaryKeyColumn(name = "push_application_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED) 17 | private UUID pushApplicationId; 18 | @PrimaryKeyColumn(name = "snapshot", ordinal = 1, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING) 19 | private Date snapshot; 20 | 21 | public DatabaseKey() { 22 | } 23 | 24 | public DatabaseKey(UUID pushApplicationId) { 25 | super(); 26 | this.pushApplicationId = pushApplicationId; 27 | this.snapshot = new Date(); 28 | } 29 | 30 | public UUID getPushApplicationId() { 31 | return pushApplicationId; 32 | } 33 | 34 | public void setPushApplicationId(UUID pushApplicationId) { 35 | this.pushApplicationId = pushApplicationId; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/model/parser/JsonRawValueDeserializer.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao.model.parser; 2 | 3 | import java.io.IOException; 4 | 5 | import com.fasterxml.jackson.core.JsonParser; 6 | import com.fasterxml.jackson.databind.DeserializationContext; 7 | import com.fasterxml.jackson.databind.JsonDeserializer; 8 | 9 | 10 | public class JsonRawValueDeserializer extends JsonDeserializer { 11 | 12 | @Override 13 | public String deserialize(JsonParser jp, DeserializationContext context) throws IOException { 14 | return jp.readValueAsTree().toString(); 15 | } 16 | } -------------------------------------------------------------------------------- /model/nosql/src/main/java/org/jboss/aerogear/unifiedpush/cassandra/dao/model/parser/UnsupportedContentTypeException.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.dao.model.parser; 2 | 3 | public class UnsupportedContentTypeException extends RuntimeException { 4 | private static final long serialVersionUID = -7644029925614901121L; 5 | 6 | public UnsupportedContentTypeException(String msg) { 7 | super(msg); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /model/nosql/src/test/java/org/jboss/aerogear/unifiedpush/cassandra/test/integration/CassandraUnitTestClassExecutionListener.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.test.integration; 2 | 3 | import org.cassandraunit.spring.CassandraUnitDependencyInjectionIntegrationTestExecutionListener; 4 | import org.springframework.test.context.TestContext; 5 | 6 | public class CassandraUnitTestClassExecutionListener 7 | extends CassandraUnitDependencyInjectionIntegrationTestExecutionListener { 8 | 9 | @Override 10 | public void beforeTestClass(TestContext testContext) throws Exception { 11 | super.beforeTestClass(testContext); 12 | } 13 | 14 | @Override 15 | public void afterTestClass(TestContext testContext) throws Exception { 16 | try { 17 | super.cleanServer(); 18 | } catch (Exception e) { 19 | // TODO: ignore exception due to 20 | // https://github.com/jsevellec/cassandra-unit/issues/220 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /model/nosql/src/test/java/org/jboss/aerogear/unifiedpush/cassandra/test/integration/FixedKeyspaceCreatingIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.cassandra.test.integration; 2 | 3 | import org.cassandraunit.spring.CassandraDataSet; 4 | import org.cassandraunit.spring.EmbeddedCassandra; 5 | import org.springframework.test.context.ActiveProfiles; 6 | import org.springframework.test.context.TestExecutionListeners; 7 | import org.springframework.test.context.TestExecutionListeners.MergeMode; 8 | 9 | /** 10 | * Base Class to prepare a fixed keyspace to give tests a keyspace context. 11 | */ 12 | @TestExecutionListeners(listeners = CassandraUnitTestClassExecutionListener.class, mergeMode = MergeMode.MERGE_WITH_DEFAULTS) 13 | @CassandraDataSet(keyspace = "unifiedpush_server", value = "cassandra-test-cql-dataload.cql") 14 | @EmbeddedCassandra 15 | @ActiveProfiles(profiles = { "default", "realtimedb" }) 16 | public class FixedKeyspaceCreatingIntegrationTest { 17 | protected void sleepSilently(long milliseconds) { 18 | try { 19 | Thread.sleep(milliseconds); 20 | } catch (InterruptedException e) { 21 | e.printStackTrace(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /model/nosql/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | aerogear.config.verification.enable_verification=false 2 | aerogear.config.verification.impl.class=org.jboss.aerogear.unifiedpush.service.sms.ClickatellSMSSender 3 | 4 | aerogear.config.oauth2.enable=false 5 | aerogear.config.oauth2.admin.username=admin 6 | aerogear.config.oauth2.admin.password=password 7 | 8 | aerogear.config.oauth2.keycloak.url=http://localhost/auth 9 | aerogear.config.oauth2.ups.admin.client=admin-cli 10 | aerogear.config.oauth2.ups.realm.name=master 11 | aerogear.config.oauth2.enforce.rooturl.protocol=https 12 | aerogear.config.oauth2.enforce.rooturl.domain= 13 | 14 | aerogear.config.cassandra.consistencylevel=ONE 15 | aerogear.config.cassandra.keyspace=unifiedpush_server 16 | aerogear.config.cassandra.contactpoints=127.0.0.1 17 | aerogear.config.cassandra.port=9142 18 | aerogear.config.cassandra.rpc_port=9171 19 | aerogear.config.cassandra.storage_port=7010 20 | aerogear.config.cassandra.ssl_storage_port=7011 21 | aerogear.config.cassandra.cql.init.timeout=60000 -------------------------------------------------------------------------------- /model/nosql/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 12 | 4.0.0 13 | 14 | org.jboss.aerogear.unifiedpush 15 | unifiedpush-parent 16 | 2.2.0.SNAPSHOT 17 | ../ 18 | 19 | 20 | unifiedpush-model-parent 21 | pom 22 | AeroBase Model Layer 23 | 24 | 25 | api 26 | push 27 | jpa 28 | nosql 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /model/push/src/main/java/org/jboss/aerogear/unifiedpush/message/Priority.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 JBoss by Red Hat. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jboss.aerogear.unifiedpush.message; 17 | 18 | /** 19 | * This is a high level priority enum which will be translated to priority 20 | * values on GCM, APNs, etc. 21 | * 22 | */ 23 | public enum Priority { 24 | 25 | NORMAL, HIGH; 26 | 27 | @Override 28 | public String toString() { 29 | return this.name().toLowerCase(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /model/push/src/main/java/org/jboss/aerogear/unifiedpush/message/json/PriorityDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 JBoss by Red Hat. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jboss.aerogear.unifiedpush.message.json; 17 | 18 | import java.io.IOException; 19 | 20 | import org.jboss.aerogear.unifiedpush.message.Priority; 21 | 22 | import com.fasterxml.jackson.core.JsonParser; 23 | import com.fasterxml.jackson.core.JsonProcessingException; 24 | import com.fasterxml.jackson.databind.DeserializationContext; 25 | import com.fasterxml.jackson.databind.JsonDeserializer; 26 | 27 | /** 28 | * Class for deserializing Priority enums. 29 | * 30 | * @author Summers Pittman 31 | */ 32 | public final class PriorityDeserializer extends JsonDeserializer { 33 | 34 | @Override 35 | public Priority deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 36 | return Priority.valueOf(jp.getText().toUpperCase()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /model/push/src/main/java/org/jboss/aerogear/unifiedpush/message/json/PrioritySerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 JBoss by Red Hat. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jboss.aerogear.unifiedpush.message.json; 17 | 18 | import java.io.IOException; 19 | 20 | import org.jboss.aerogear.unifiedpush.message.Priority; 21 | 22 | import com.fasterxml.jackson.core.JsonGenerator; 23 | import com.fasterxml.jackson.core.JsonProcessingException; 24 | import com.fasterxml.jackson.databind.JsonSerializer; 25 | import com.fasterxml.jackson.databind.SerializerProvider; 26 | 27 | /** 28 | * 29 | * Class for serializing Priority enums. 30 | * 31 | * @author Summers Pittman 32 | */ 33 | public final class PrioritySerializer extends JsonSerializer { 34 | 35 | @Override 36 | public void serialize(Priority value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { 37 | jgen.writeString(value.toString()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /model/push/src/main/java/org/jboss/aerogear/unifiedpush/message/windows/BadgeType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.windows; 18 | 19 | /** 20 | * Badge notifications type for badges that are not numbers, for numbers use the value in the main part of the message. 21 | * Tile and badge catalog 22 | */ 23 | public enum BadgeType { 24 | none, 25 | activity, 26 | alert, 27 | available, 28 | away, 29 | busy, 30 | newMessage, 31 | paused, 32 | playing, 33 | unavailable, 34 | error, 35 | attention 36 | } 37 | -------------------------------------------------------------------------------- /model/push/src/main/java/org/jboss/aerogear/unifiedpush/message/windows/DurationType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.windows; 18 | 19 | /** 20 | * Duration a Toast message is displayed long or short 21 | * xml schema 22 | */ 23 | public enum DurationType { 24 | SHORT("short"), 25 | LONG("long"); 26 | private final String name; 27 | 28 | DurationType(String name) { 29 | this.name = name; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return name; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /model/push/src/main/java/org/jboss/aerogear/unifiedpush/message/windows/ToastType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.windows; 18 | 19 | /** 20 | * Toast template catalog 21 | */ 22 | public enum ToastType { 23 | ToastText01, 24 | ToastText02, 25 | ToastText03, 26 | ToastText04, 27 | 28 | ToastImageAndText01, 29 | ToastImageAndText02, 30 | ToastImageAndText03, 31 | ToastImageAndText04 32 | } 33 | -------------------------------------------------------------------------------- /model/push/src/main/java/org/jboss/aerogear/unifiedpush/message/windows/Type.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.windows; 18 | 19 | /** 20 | * The type of message to send toast, raw, badge or tile. 21 | * From more info about the types 22 | */ 23 | public enum Type { 24 | badge, 25 | raw, 26 | tile, 27 | toast 28 | } 29 | -------------------------------------------------------------------------------- /model/push/src/test/resources/message-format.json: -------------------------------------------------------------------------------- 1 | { 2 | "message": { 3 | "alert": "HELLO!", 4 | "sound": "default", 5 | "badge": 2, 6 | "consolidationKey": null, 7 | "priority": "normal", 8 | "windows": { 9 | "type": "tile", 10 | "duration": null, 11 | "badge": null, 12 | "tileType": "TileWideBlockAndText01", 13 | "toastType": null, 14 | "images": [ 15 | ], 16 | "textFields": [ 17 | ], 18 | "page": "/MainPage.xaml" 19 | }, 20 | "apns": { 21 | "title": null, 22 | "action": null, 23 | "action-category": "some value", 24 | "url-args": null, 25 | "content-available": true, 26 | "localized-key": null, 27 | "localized-arguments": null, 28 | "localized-title-key": null, 29 | "localized-title-arguments": null 30 | }, 31 | 32 | "user-data": { 33 | "key2": "other value", 34 | "key": "value" 35 | }, 36 | "simple-push": "version=123" 37 | }, 38 | "criteria": { 39 | "categories": [ 40 | "someCategories" 41 | ], 42 | "variants": [ 43 | "someVariantIDs" 44 | ], 45 | "alias": [ 46 | "someUsername" 47 | ], 48 | "deviceType": [ 49 | "someDevice" 50 | ] 51 | }, 52 | "config": { 53 | "ttl": 3360 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /model/push/src/test/resources/message-high-priority.json: -------------------------------------------------------------------------------- 1 | { 2 | "message": { 3 | "alert": "HELLO!", 4 | "sound": "default", 5 | "badge": 2, 6 | "consolidationKey": null, 7 | "priority": "HIGH" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /model/push/src/test/resources/message-normal-priority.json: -------------------------------------------------------------------------------- 1 | { 2 | "message": { 3 | "alert": "HELLO!", 4 | "sound": "default", 5 | "badge": 2, 6 | "consolidationKey": null, 7 | "priority": "normal" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /model/push/src/test/resources/message-tojson.json: -------------------------------------------------------------------------------- 1 | { 2 | "alert": "HELLO!", 3 | "priority": "normal", 4 | "badge": "2", 5 | "criteria": { 6 | "categories": null, 7 | "variants": null, 8 | "alias": null, 9 | "deviceType": null 10 | }, 11 | "config": { 12 | "ttl": -1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /model/push/src/test/resources/message-tostrippedjson.json: -------------------------------------------------------------------------------- 1 | { 2 | "alert": "HELLO!", 3 | "priority": "normal", 4 | "badge": "2", 5 | "criteria": { 6 | "categories": null, 7 | "variants": null, 8 | "alias": null, 9 | "deviceType": null 10 | }, 11 | "config": { 12 | "ttl": -1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /node.js/README.md: -------------------------------------------------------------------------------- 1 | Before running the test script, make sure to add a new client in the Keycloak Admin Console: 2 | http://localhost:8080/auth/admin/aerogear/console/ 3 | 4 | The new client needs to be called `ups-client`, and make sure `Direct Grants Only` are _ON_. It is also _required_ to set the `Access Type` to `public`. 5 | 6 | The other options are not relevant to execute the script. Once done, the script can be executed via: 7 | ``` 8 | node directgranttest.js 9 | ``` 10 | 11 | Afterwards a new `Push Application` should be visible in the UI. 12 | 13 | __NOTE:__ The test/demo script LACKS the password for admin... 14 | -------------------------------------------------------------------------------- /openshift/README.md: -------------------------------------------------------------------------------- 1 | # UnifiedPush Server in OpenShift 2 | 3 | Make sure you have at least two 1G persistent volumes provisioned, then create a new project: 4 | ```bash 5 | $ oc new-project ups 6 | ``` 7 | 8 | Create the OpenShift UPS application: 9 | ```bash 10 | $ oc new-app -f ups-template.json -n ups 11 | ``` 12 | 13 | Run `oc get pods -w` and monitor until all pods are in the `Running` state, and you're good to go. 14 | The UnifiedPush server should be available at `http://ups.127.0.0.1.nip.io/ag-push`. 15 | 16 | -------------------------------------------------------------------------------- /push-sender/src/main/java/org/jboss/aerogear/unifiedpush/message/HealthNetworkService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message; 18 | 19 | import org.jboss.aerogear.unifiedpush.service.impl.health.HealthDetails; 20 | 21 | import java.util.List; 22 | import java.util.concurrent.Future; 23 | 24 | /** 25 | * Finds out about the status of the push networks 26 | */ 27 | public interface HealthNetworkService { 28 | /** 29 | * Get the status about the push networks. 30 | * If one of them is not reachable Status.WARN 31 | * @return a list of HealthDetails with the status of each PushNetwork 32 | */ 33 | Future> networkStatus(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /push-sender/src/main/java/org/jboss/aerogear/unifiedpush/message/SenderConfig.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.message; 2 | 3 | import org.jboss.aerogear.unifiedpush.event.iOSVariantUpdateEvent; 4 | import org.jboss.aerogear.unifiedpush.message.configuration.SenderConfigurationProvider; 5 | import org.jboss.aerogear.unifiedpush.message.holder.MessageHolderWithTokens; 6 | import org.jboss.aerogear.unifiedpush.message.holder.MessageHolderWithVariants; 7 | import org.jboss.aerogear.unifiedpush.message.token.TokenLoader.TokenLoaderWrapper; 8 | import org.jboss.aerogear.unifiedpush.spring.ServiceConfig; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.ComponentScan; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.context.annotation.Import; 13 | 14 | import reactor.core.publisher.TopicProcessor; 15 | import reactor.core.publisher.WorkQueueProcessor; 16 | 17 | @Configuration 18 | @Import({ ServiceConfig.class }) 19 | @ComponentScan(basePackageClasses = { SenderConfig.class, SenderConfigurationProvider.class, TokenLoaderWrapper.class }) 20 | public class SenderConfig { 21 | public static final int BUFFER_SIZE = 256 * 256; 22 | 23 | @Bean 24 | public WorkQueueProcessor getTokensProcessor() { 25 | return WorkQueueProcessor.builder().bufferSize(BUFFER_SIZE).build(); 26 | } 27 | 28 | @Bean 29 | public TopicProcessor getBatchProcessor() { 30 | return TopicProcessor.builder().bufferSize(BUFFER_SIZE).build(); 31 | } 32 | 33 | @Bean 34 | public WorkQueueProcessor getIOsVariantUpdateProcessor() { 35 | return WorkQueueProcessor.builder().build(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /push-sender/src/main/java/org/jboss/aerogear/unifiedpush/message/cache/ServiceConstructor.java: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * JBoss, Home of Professional Open Source 4 | * Copyright Red Hat, Inc., and individual contributors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jboss.aerogear.unifiedpush.message.cache; 19 | 20 | /** 21 | * Allows to create a new service of type T 22 | */ 23 | public interface ServiceConstructor { 24 | 25 | /** 26 | * Create a new service of type T 27 | * 28 | * @return a new service instance or null if creation failed 29 | */ 30 | T construct(); 31 | } 32 | -------------------------------------------------------------------------------- /push-sender/src/main/java/org/jboss/aerogear/unifiedpush/message/event/AllBatchesLoadedEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.event; 18 | 19 | import java.io.Serializable; 20 | 21 | /** 22 | * Event fired when all batches for given variant were loaded and queued. 23 | * 24 | * Note: this does not mean all batches are processed. 25 | * 26 | * @see BatchLoadedEvent 27 | */ 28 | public class AllBatchesLoadedEvent implements Serializable { 29 | 30 | private static final long serialVersionUID = 3259364604967570821L; 31 | 32 | private String variantID; 33 | 34 | public AllBatchesLoadedEvent(String variantID) { 35 | this.variantID = variantID; 36 | } 37 | 38 | public String getVariantID() { 39 | return variantID; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /push-sender/src/main/java/org/jboss/aerogear/unifiedpush/message/event/BatchLoadedEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.event; 18 | 19 | import java.io.Serializable; 20 | 21 | /** 22 | * Event fired when one batch for given variant was loaded and queued. 23 | * 24 | * @see AllBatchesLoadedEvent 25 | */ 26 | public class BatchLoadedEvent implements Serializable { 27 | 28 | private static final long serialVersionUID = 1897563219239181838L; 29 | 30 | private String variantID; 31 | 32 | public BatchLoadedEvent(String variantID) { 33 | this.variantID = variantID; 34 | } 35 | 36 | public String getVariantID() { 37 | return variantID; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /push-sender/src/main/java/org/jboss/aerogear/unifiedpush/message/exception/MessageDeliveryException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.exception; 18 | 19 | /** 20 | * Thrown when messaging subsystem fails to queue the notification for processing, so that the push notification couldn't be delivered 21 | */ 22 | public class MessageDeliveryException extends RuntimeException { 23 | 24 | private static final long serialVersionUID = 5679901095720892005L; 25 | 26 | public MessageDeliveryException() { 27 | super(); 28 | } 29 | 30 | public MessageDeliveryException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 31 | super(message, cause, enableSuppression, writableStackTrace); 32 | } 33 | 34 | public MessageDeliveryException(String message, Throwable cause) { 35 | super(message, cause); 36 | } 37 | 38 | public MessageDeliveryException(String message) { 39 | super(message); 40 | } 41 | 42 | public MessageDeliveryException(Throwable cause) { 43 | super(cause); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /push-sender/src/main/java/org/jboss/aerogear/unifiedpush/message/exception/SenderResourceNotAvailableException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.exception; 18 | 19 | import org.jboss.aerogear.unifiedpush.message.sender.PushNotificationSender; 20 | 21 | /** 22 | * Thrown when {@link PushNotificationSender} failed to lock the resource it needs e.g. for establishing connection with Push Network. 23 | * 24 | * In such a case, the message will be considered not dispatched and messaging subsystem will try to deliver message later. 25 | */ 26 | public class SenderResourceNotAvailableException extends DispatchInitiationException { 27 | 28 | private static final long serialVersionUID = -3279031099595849939L; 29 | 30 | public SenderResourceNotAvailableException(String message, Throwable cause) { 31 | super(message, cause); 32 | } 33 | 34 | public SenderResourceNotAvailableException(String message) { 35 | super(message); 36 | } 37 | 38 | public SenderResourceNotAvailableException(Throwable cause) { 39 | super(cause); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /push-sender/src/main/java/org/jboss/aerogear/unifiedpush/message/sender/NotificationSenderCallback.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.sender; 18 | 19 | /** 20 | * A simple Callback interface used when sending {@link org.jboss.aerogear.unifiedpush.message.UnifiedPushMessage} to 21 | * an actual push network. 22 | */ 23 | public interface NotificationSenderCallback { 24 | 25 | /** 26 | * Simple indicator which will be called on a successful to deliver to the push network. However, the invocation of 27 | * this callback does NOT mean the messages have been sent out to the mobile devices. The invocation simply means 28 | * the {@link org.jboss.aerogear.unifiedpush.message.sender.PushNotificationSender} was able to send the messages to 29 | * the push network for its further processing 30 | */ 31 | void onSuccess(); 32 | 33 | /** 34 | * Simple indicator which will be called on any type of error that occurred while sending the payload to the 35 | * underlying push network. 36 | * 37 | * @param reason details about the error 38 | */ 39 | void onError(String reason); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /push-sender/src/main/java/org/jboss/aerogear/unifiedpush/message/sender/fcm/ConfigurableFCMSender.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.message.sender.fcm; 18 | 19 | import java.io.IOException; 20 | import java.net.HttpURLConnection; 21 | import java.net.URL; 22 | 23 | import org.jboss.aerogear.unifiedpush.system.ConfigurationUtils; 24 | 25 | import com.google.android.gcm.server.Sender; 26 | 27 | public class ConfigurableFCMSender extends Sender { 28 | 29 | public static final String CUSTOM_AEROGEAR_FCM_PUSH_HOST = "custom.aerogear.fcm.push.host"; 30 | 31 | public static final String FCM_ENDPOINT_HOST = "https://fcm.googleapis.com/fcm/send"; 32 | 33 | public ConfigurableFCMSender(String key) { 34 | super(key); 35 | } 36 | 37 | @Override 38 | protected HttpURLConnection getConnection(String url) throws IOException { 39 | 40 | // let's see if there is a different URL we should post to (e.g. load/stress testing) 41 | final String fcmURL = ConfigurationUtils.tryGetProperty(CUSTOM_AEROGEAR_FCM_PUSH_HOST, FCM_ENDPOINT_HOST); 42 | 43 | return (HttpURLConnection) new URL(fcmURL).openConnection(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /push-sender/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /push-sender/src/test/filtered-resources/default.properties: -------------------------------------------------------------------------------- 1 | aerogear.config.verification.enable_verification=false 2 | aerogear.config.verification.impl.class=org.jboss.aerogear.unifiedpush.service.sms.ClickatellSMSSender 3 | 4 | aerogear.config.oauth2.enable=false 5 | aerogear.config.oauth2.admin.username=admin 6 | aerogear.config.oauth2.admin.password=password 7 | 8 | aerogear.config.oauth2.keycloak.url=http://localhost/auth 9 | aerogear.config.oauth2.ups.admin.client=admin-cli 10 | aerogear.config.oauth2.ups.realm.name=master 11 | aerogear.config.oauth2.enforce.rooturl.protocol=https 12 | aerogear.config.oauth2.enforce.rooturl.domain= 13 | 14 | aerogear.config.cassandra.consistencylevel=ONE 15 | aerogear.config.cassandra.keyspace=unifiedpush_server 16 | aerogear.config.cassandra.contactpoints=127.0.0.1 17 | aerogear.config.cassandra.port=9142 18 | aerogear.config.cassandra.rpc_port=9171 19 | aerogear.config.cassandra.storage_port=7010 20 | aerogear.config.cassandra.ssl_storage_port=7011 21 | aerogear.config.cassandra.cql.init.timeout=60000 -------------------------------------------------------------------------------- /push-sender/src/test/java/org/jboss/aerogear/unifiedpush/message/DeviceTokenValidatorTest.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.message; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.apache.commons.lang3.RandomStringUtils; 6 | import org.jboss.aerogear.unifiedpush.api.VariantType; 7 | import org.jboss.aerogear.unifiedpush.api.validation.DeviceTokenValidator; 8 | import org.junit.Test; 9 | 10 | public class DeviceTokenValidatorTest { 11 | private static final char[] iosTokenChars = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', '1', '2', '3', '4', '5', '6', 12 | '7', '8', '9', '0', ' ', '-' }; 13 | 14 | @Test 15 | public void testRandomToken() { 16 | final VariantType iosVariantType = VariantType.IOS; 17 | assertThat(DeviceTokenValidator.isValidDeviceTokenForVariant(RandomStringUtils.random(65, iosTokenChars), 18 | iosVariantType)).isTrue(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /push-sender/src/test/resources/META-INF/db.properties: -------------------------------------------------------------------------------- 1 | # H2 connection string 2 | jdbcUrl=jdbc:h2:mem:unifiedpush;LOCK_TIMEOUT=10000 3 | 4 | dataSource.dataSource=true 5 | dataSource.prepStmtCacheSize=250 6 | dataSource.prepStmtCacheSqlLimit=2048 7 | dataSource.useServerPrepStmts=true 8 | 9 | # Maximum number of JDBC connections in the pool. Hibernate default: 100 10 | maximumPoolSize=100 11 | # Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire. Default: 300 12 | idleTimeout=300 -------------------------------------------------------------------------------- /push-sender/src/test/resources/META-INF/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.dialect=org.hibernate.dialect.H2Dialect 2 | hibernate.hbm2ddl.import_files=META-INF/test-data.sql 3 | hibernate.hbm2ddl.auto=create 4 | hibernate.show_sql=false 5 | hibernate.format_sql=false 6 | hibernate.transaction.flush_before_completion=true 7 | hibernate.id.new_generator_mappings=true -------------------------------------------------------------------------------- /push-sender/src/test/resources/META-INF/test-data.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- H2 database query 3 | -- 4 | 5 | INSERT INTO push_application VALUES ('711c8b98-9c2c-4d94-abe7-ecff7145c015', NULL, 'admin', '1f73558f-d01b-48d7-9f6a-fc5d0ec6da51', 'DEFAULT', '7385c294-2003-4abf-83f6-29a27415326b'); 6 | 7 | INSERT INTO variant VALUES ('ios', '5ede4a1b-0277-4467-992c-02a7b307e555', NULL, 'admin', 'DEFAULT', '088a814a-ff2b-4acf-9091-5bcd0ccece16', 1, 'd3f54c25-c3ce-4999-b7a8-27dc9bb01364', '711c8b98-9c2c-4d94-abe7-ecff7145c015'); 8 | 9 | INSERT INTO ios_variant VALUES ('TBD123', 'TBD123', false, '5ede4a1b-0277-4467-992c-02a7b307e555'); 10 | 11 | 12 | -------------------------------------------------------------------------------- /push-sender/src/test/resources/cert/certificate.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aerobase/unifiedpush-server/43430e1c3abaf62b331cbbeb6dd8036b81f3ca8a/push-sender/src/test/resources/cert/certificate.p12 -------------------------------------------------------------------------------- /push-sender/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /servers/README.txt: -------------------------------------------------------------------------------- 1 | The aerogear UPS application http://localhost:8080/unifiedpush-server 2 | The aerogear security admin (keycloak) http://localhost:8080/auth/admin/aerogear/console/index.html 3 | The aerogear user account page (keycloak) http://localhost:8080/auth/realms/aerogear/account -------------------------------------------------------------------------------- /servers/src/main/java/org/jboss/aerogear/unifiedpush/auth/BasicAuthenticationRequestMatcher.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.auth; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.jboss.aerogear.unifiedpush.rest.util.HttpBasicHelper; 7 | import org.springframework.security.web.util.matcher.RequestMatcher; 8 | 9 | public class BasicAuthenticationRequestMatcher implements RequestMatcher { 10 | private static final String AUTHORIZATION_HEADER = "Authorization"; 11 | 12 | private final String expectedHeaderName = AUTHORIZATION_HEADER; 13 | private final String expectedHeaderValue = HttpBasicHelper.HTTP_BASIC_SCHEME.trim(); 14 | 15 | public boolean matches(HttpServletRequest request) { 16 | String actualHeaderValue = request.getHeader(expectedHeaderName); 17 | if (StringUtils.isEmpty(actualHeaderValue)) { 18 | return false; 19 | } 20 | 21 | return actualHeaderValue.trim().startsWith(expectedHeaderValue); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "RequestHeaderRequestMatcher [expectedHeaderName=" + expectedHeaderName + ", expectedHeaderValue=" 27 | + expectedHeaderValue + "]"; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /servers/src/main/java/org/jboss/aerogear/unifiedpush/auth/CustomKeycloakDeployment.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.auth; 2 | 3 | import org.keycloak.adapters.KeycloakDeployment; 4 | import org.keycloak.common.util.KeycloakUriBuilder; 5 | 6 | public class CustomKeycloakDeployment extends KeycloakDeployment { 7 | 8 | public void setAuthUrl(KeycloakUriBuilder authUrl) { 9 | this.authUrl = authUrl; 10 | } 11 | 12 | public void setRealmInfoUrl(String realmInfoUrl) { 13 | this.realmInfoUrl = realmInfoUrl; 14 | } 15 | 16 | public void setTokenUrl(String tokenUrl) { 17 | this.tokenUrl = tokenUrl; 18 | } 19 | 20 | public void setLogoutUrl(KeycloakUriBuilder logoutUrl) { 21 | this.logoutUrl = logoutUrl; 22 | } 23 | 24 | public void setAccountUrl(String accountUrl) { 25 | this.accountUrl = accountUrl; 26 | } 27 | 28 | public void setRegisterNodeUrl(String registerNodeUrl) { 29 | this.registerNodeUrl = registerNodeUrl; 30 | } 31 | 32 | public void setUnregisterNodeUrl(String unregisterNodeUrl) { 33 | this.unregisterNodeUrl = unregisterNodeUrl; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /servers/src/main/java/org/jboss/aerogear/unifiedpush/auth/CustomKeycloakDeploymentBuilder.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.auth; 2 | 3 | import java.io.InputStream; 4 | 5 | import org.jboss.aerogear.unifiedpush.service.impl.spring.OAuth2Configuration; 6 | import org.keycloak.adapters.KeycloakDeploymentBuilder; 7 | import org.keycloak.representations.adapters.config.AdapterConfig; 8 | 9 | public class CustomKeycloakDeploymentBuilder extends KeycloakDeploymentBuilder { 10 | 11 | public CustomKeycloakDeploymentBuilder() { 12 | deployment = new CustomKeycloakDeployment(); 13 | } 14 | 15 | public static CustomKeycloakDeployment build(InputStream inputStream, String realmName, String clientName) { 16 | AdapterConfig adapterConfig = loadAdapterConfig(inputStream); 17 | 18 | // Override realm attributes from system properties if exists. 19 | String upsAuthServer = OAuth2Configuration.getStaticOAuth2Url(); 20 | 21 | // This override properties from static WEB-INF json files. 22 | adapterConfig.setResource(clientName); 23 | adapterConfig.setRealm(realmName); 24 | 25 | adapterConfig.setAuthServerUrl(upsAuthServer); 26 | 27 | return (CustomKeycloakDeployment) new CustomKeycloakDeploymentBuilder().internalBuild(adapterConfig); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /servers/src/main/resources/META-INF/db.properties: -------------------------------------------------------------------------------- 1 | # Postgres connection string 2 | jdbcUrl=jdbc:postgresql://localhost:5432/unifiedpush_server 3 | username=aerobase_server 4 | password= 5 | 6 | dataSource.dataSource=true 7 | dataSource.prepStmtCacheSize=250 8 | dataSource.prepStmtCacheSqlLimit=2048 9 | dataSource.useServerPrepStmts=true 10 | 11 | # Maximum number of JDBC connections in the pool. Hibernate default: 100 12 | maximumPoolSize=25 13 | # Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire. Default: 300 14 | idleTimeout=300 -------------------------------------------------------------------------------- /servers/src/main/resources/META-INF/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.dialect=org.hibernate.dialect.PostgreSQL95Dialect 2 | hibernate.hbm2ddl.auto=validate 3 | hibernate.show_sql=false 4 | hibernate.format_sql=false 5 | hibernate.transaction.flush_before_completion=true 6 | hibernate.id.new_generator_mappings=true -------------------------------------------------------------------------------- /servers/src/main/resources/default.properties: -------------------------------------------------------------------------------- 1 | aerogear.config.verification.enable_verification=false 2 | aerogear.config.verification.impl.class=org.jboss.aerogear.unifiedpush.service.validation.PhoneValidator::org.jboss.aerogear.unifiedpush.service.sms.ClickatellSMSSender;org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator::org.jboss.aerogear.unifiedpush.service.sms.SSLEmailSender 3 | 4 | aerogear.config.oauth2.enable=true 5 | aerogear.config.oauth2.admin.username=admin 6 | aerogear.config.oauth2.admin.password=password 7 | 8 | aerogear.config.oauth2.keycloak.url=http://localhost/auth 9 | aerogear.config.oauth2.ups.admin.client=admin-cli 10 | aerogear.config.oauth2.ups.realm.name=master 11 | aerogear.config.oauth2.enforce.rooturl.protocol=https 12 | aerogear.config.oauth2.enforce.rooturl.domain= 13 | -------------------------------------------------------------------------------- /servers/src/main/webapp/META-INF/log4j.xml: -------------------------------------------------------------------------------- 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 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /servers/src/main/webapp/WEB-INF/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /servers/src/main/webapp/WEB-INF/jboss-deployment-structure.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /servers/src/main/webapp/WEB-INF/jboss-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /servers/src/main/webapp/WEB-INF/keycloak-proxy.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm": "SHOULD-BE-REPLACED-IN-JAVA", 3 | "auth-server-url" : "/auth", 4 | "ssl-required" : "external", 5 | "resource" : "admin-cli", 6 | "bearer-only" : true, 7 | "enable-cors" : true, 8 | "disable-trust-manager" : true 9 | } -------------------------------------------------------------------------------- /servers/src/main/webapp/WEB-INF/keycloak.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm" : "SHOULD-BE-REPLACED-IN-JAVA", 3 | "auth-server-url" : "/auth", 4 | "ssl-required" : "external", 5 | "resource" : "aerobase", 6 | "bearer-only" : true, 7 | "disable-trust-manager" : true 8 | } 9 | 10 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/ClientInstallationAsyncService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service; 18 | 19 | import java.util.List; 20 | import java.util.Set; 21 | 22 | import org.jboss.aerogear.unifiedpush.api.Installation; 23 | import org.jboss.aerogear.unifiedpush.api.Variant; 24 | 25 | /** 26 | * Service class used by the Server to work with Installations for the different 27 | * Variants. 28 | */ 29 | public interface ClientInstallationAsyncService { 30 | 31 | public void addInstallation(Variant variant, Installation entity); 32 | 33 | public void addInstallations(Variant variant, List installations); 34 | 35 | public void removeInstallationsForVariantByDeviceTokens(String variantID, Set deviceTokens); 36 | 37 | public void removeInstallationForVariantByDeviceToken(String variantID, String deviceToken); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/DocumentService.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service; 2 | 3 | import java.util.List; 4 | import java.util.UUID; 5 | import java.util.stream.Stream; 6 | 7 | import org.jboss.aerogear.unifiedpush.api.Alias; 8 | import org.jboss.aerogear.unifiedpush.api.PushApplication; 9 | import org.jboss.aerogear.unifiedpush.api.document.DocumentMetadata; 10 | import org.jboss.aerogear.unifiedpush.api.document.QueryOptions; 11 | import org.jboss.aerogear.unifiedpush.cassandra.dao.model.DocumentContent; 12 | 13 | public interface DocumentService { 14 | 15 | DocumentContent save(DocumentContent doc); 16 | 17 | DocumentContent save(DocumentMetadata metadata, String content, String id); 18 | 19 | void delete(String pushApplicationId); 20 | 21 | void delete(UUID pushApplicaitonId, Alias alias); 22 | 23 | DocumentContent findLatest(DocumentMetadata metadata, String id); 24 | 25 | Stream find(DocumentMetadata metadata, QueryOptions options); 26 | 27 | List findLatest(PushApplication pushApp, String database, String id, List aliases); 28 | } 29 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/HealthDBService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service; 18 | 19 | import java.util.concurrent.Future; 20 | 21 | import org.jboss.aerogear.unifiedpush.service.impl.health.HealthDetails; 22 | 23 | /** 24 | * Service query database to see how how healthy we are. 25 | */ 26 | public interface HealthDBService { 27 | /** 28 | * Get the database status and return a HealthDetails. 29 | * If the database is reachable and functioning Status.OK otherwise Status.CRIT 30 | * @see org.jboss.aerogear.unifiedpush.service.impl.health.Status 31 | * @return the HealthDetails with the current database health 32 | */ 33 | Future dbStatus(); 34 | } 35 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/PostDelete.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service; 2 | 3 | public interface PostDelete { 4 | public void after(); 5 | } 6 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/annotations/LoggedInUser.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service.annotations; 18 | 19 | /** 20 | * Current logged in user 21 | */ 22 | 23 | public class LoggedInUser { 24 | private String user; 25 | 26 | public LoggedInUser(String user) { 27 | super(); 28 | this.user = user; 29 | } 30 | 31 | public String getUser() { 32 | return user; 33 | } 34 | 35 | public void setUser(String user) { 36 | this.user = user; 37 | } 38 | 39 | public String get() { 40 | return user; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/impl/ServiceConstraintViolationException.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.impl; 2 | 3 | public class ServiceConstraintViolationException extends RuntimeException { 4 | private static final long serialVersionUID = -1278939900905611731L; 5 | 6 | private final String entityId; 7 | 8 | public ServiceConstraintViolationException(Throwable e, String entityId) { 9 | super(e); 10 | this.entityId = entityId; 11 | } 12 | 13 | public String getEntityId() { 14 | return entityId; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/impl/health/PushNetwork.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service.impl.health; 18 | 19 | /** 20 | * Readonly holder of Push network information 21 | */ 22 | public class PushNetwork { 23 | private String name; 24 | private String host; 25 | private int port; 26 | 27 | public PushNetwork(String name, String host, int port) { 28 | this.name = name; 29 | this.host = host; 30 | this.port = port; 31 | } 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | public String getHost() { 38 | return host; 39 | } 40 | 41 | public int getPort() { 42 | return port; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/impl/health/Status.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service.impl.health; 18 | 19 | import com.fasterxml.jackson.annotation.JsonValue; 20 | 21 | /** 22 | * status 23 | */ 24 | public enum Status { 25 | OK("ok"), 26 | WARN("warn"), 27 | CRIT("crit"); 28 | 29 | private final String name; 30 | 31 | Status(String name) { 32 | this.name = name; 33 | } 34 | 35 | @JsonValue 36 | public String getName() { 37 | return name; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/impl/spring/ConfigurationServiceImpl.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.impl.spring; 2 | 3 | import java.util.Properties; 4 | 5 | import org.jboss.aerogear.unifiedpush.system.ConfigurationEnvironment; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | * EJB singleton wrapper bean. Wraps spring configuration environments and beans. 11 | */ 12 | @Service 13 | public class ConfigurationServiceImpl implements IConfigurationService { 14 | @Autowired 15 | private ConfigurationEnvironment environment; 16 | @Autowired 17 | private IOAuth2Configuration oAuth2Configuration; 18 | 19 | /* 20 | * Number of days period to query existing documents. 21 | */ 22 | public Integer getQueryDefaultPeriodInDays() { 23 | return environment.getQueryDefaultPeriodInDays(); 24 | } 25 | 26 | public Properties getProperties() { 27 | return environment.getProperties(); 28 | } 29 | 30 | public String getOAuth2Url() { 31 | return oAuth2Configuration.getOAuth2Url(); 32 | } 33 | 34 | public String getUpsRealm() { 35 | return oAuth2Configuration.getUpsRealm(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/impl/spring/IConfigurationService.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.impl.spring; 2 | 3 | import java.util.Properties; 4 | 5 | public interface IConfigurationService { 6 | Properties getProperties(); 7 | 8 | Integer getQueryDefaultPeriodInDays(); 9 | 10 | String getOAuth2Url(); 11 | 12 | String getUpsRealm(); 13 | } 14 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/impl/spring/IKeycloakService.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.impl.spring; 2 | 3 | import java.util.List; 4 | 5 | import org.jboss.aerogear.unifiedpush.api.PushApplication; 6 | import org.jboss.aerogear.unifiedpush.service.annotations.LoggedInUser; 7 | import org.springframework.cache.annotation.Cacheable; 8 | 9 | public interface IKeycloakService { 10 | public static final String CACHE_NAME = "variant-ids-per-clientid"; 11 | 12 | void createRealmIfAbsent(LoggedInUser accountName, PushApplication pushApplication); 13 | 14 | void createClientIfAbsent(LoggedInUser accountName, PushApplication pushApplication); 15 | 16 | void removeClient(LoggedInUser accountName, PushApplication pushApplicaiton); 17 | 18 | boolean exists(LoggedInUser accountName, String userName); 19 | 20 | void delete(LoggedInUser accountName, String userName); 21 | 22 | @Cacheable(value = IKeycloakService.CACHE_NAME, unless = "#result == null") 23 | List getVariantIdsFromClient(LoggedInUser accountName, String clientId); 24 | 25 | void updateUserPassword(LoggedInUser accountName, String aliasId, String currentPassword, String newPassword); 26 | 27 | boolean isInitialized(); 28 | 29 | String stripApplicationName(String fqdn); 30 | 31 | String stripAccountName(String fqdn); 32 | 33 | String toRealmName(LoggedInUser account); 34 | 35 | String getClientName(LoggedInUser account, String applicationName); 36 | 37 | Boolean setPortalMode(Boolean mode); 38 | } 39 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/impl/spring/IOAuth2Configuration.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.impl.spring; 2 | 3 | import org.jboss.aerogear.unifiedpush.service.impl.spring.OAuth2Configuration.DomainMatcher; 4 | 5 | interface IOAuth2Configuration { 6 | 7 | boolean isOAuth2Enabled(); 8 | 9 | String getOAuth2Url(); 10 | 11 | String getUpsRealm(); 12 | 13 | String getAdminClient(); 14 | 15 | String getAdminUserName(); 16 | 17 | String getAdminPassword(); 18 | 19 | String getRooturlDomain(); 20 | 21 | String getRooturlProtocol(); 22 | 23 | DomainMatcher getRooturlMatcher(); 24 | 25 | Boolean isPortalMode(); 26 | } 27 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/metrics/DeleteOldPushMessageInformationScheduler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service.metrics; 18 | 19 | import javax.inject.Inject; 20 | 21 | import org.springframework.scheduling.annotation.Scheduled; 22 | import org.springframework.stereotype.Service; 23 | 24 | @Service 25 | public class DeleteOldPushMessageInformationScheduler { 26 | 27 | @Inject 28 | private IPushMessageMetricsService service; 29 | 30 | /** 31 | * Job that triggers a delete of outdated metric information from the Server. 32 | * 33 | * Note: Occurring every day at midnight in the default time zone associated with the container 34 | * in which the application is executing. These are the default values from the @Schedule annotation. 35 | */ 36 | @Scheduled(cron = "0 24 * * *") 37 | public void deleteOutdatedFlatMetrics() { 38 | service.deleteOutdatedFlatPushInformationData(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/metrics/IPushMessageMetricsService.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.metrics; 2 | 3 | import org.jboss.aerogear.unifiedpush.api.FlatPushMessageInformation; 4 | import org.jboss.aerogear.unifiedpush.api.Variant; 5 | import org.jboss.aerogear.unifiedpush.dao.PageResult; 6 | import org.jboss.aerogear.unifiedpush.dto.MessageMetrics; 7 | 8 | public interface IPushMessageMetricsService { 9 | 10 | FlatPushMessageInformation storeNewRequestFrom(String pushAppId, String json, String ipAddress, 11 | String clientIdentifier); 12 | 13 | void updatePushMessageInformation(FlatPushMessageInformation pushMessageInformation); 14 | 15 | void appendError(FlatPushMessageInformation pushMessageInformation, Variant variant, String errorMessage); 16 | 17 | PageResult findAllFlatsForPushApplication(String pushApplicationID, 18 | String search, boolean sorting, Integer page, Integer pageSize); 19 | 20 | /** 21 | * Returns number of push messages for given push application ID 22 | * 23 | * @param pushApplicationId the push app ID 24 | * 25 | * @return the number of message for the given push application 26 | */ 27 | long countMessagesForPushApplication(String pushApplicationId); 28 | 29 | /** 30 | * We trigger a delete of all {@link org.jboss.aerogear.unifiedpush.api.FlatPushMessageInformation} objects that are 31 | * older than 30 days! 32 | */ 33 | void deleteOutdatedFlatPushInformationData(); 34 | 35 | void updateAnalytics(String aerogearPushId); 36 | 37 | FlatPushMessageInformation getPushMessageInformation(String id); 38 | 39 | } -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/validation/ApplicationValidation.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.validation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import javax.validation.Constraint; 10 | 11 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Constraint(validatedBy = ApplicationValidator.class) 14 | @Documented 15 | public @interface ApplicationValidation { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/validation/ApplicationValidator.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.validation; 2 | 3 | import javax.validation.ConstraintValidator; 4 | import javax.validation.ConstraintValidatorContext; 5 | 6 | public class ApplicationValidator implements ConstraintValidator { 7 | public static final String APP_VALIDATION_KEY = "aerogear.config.application.specific.validation.ids"; 8 | private static final String APPLICATION_SEPERATOR = ";"; 9 | 10 | @Override 11 | public void initialize(ApplicationValidation constraintAnnotation) { 12 | } 13 | 14 | @Override 15 | public boolean isValid(String value, ConstraintValidatorContext context) { 16 | ConstraintValidatorContextImpl contextImpl = context.unwrap(ConstraintValidatorContextImpl.class); 17 | String applicationIds = contextImpl.getProperties().getProperty(APP_VALIDATION_KEY); 18 | 19 | if (applicationIds == null | applicationIds.length() == 0) 20 | return false; 21 | 22 | String[] ids = applicationIds.split(APPLICATION_SEPERATOR); 23 | 24 | for (String id : ids) { 25 | if (id.equals(contextImpl.getPushApplicationId())) { 26 | return true; 27 | } 28 | } 29 | 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/validation/PhoneValidation.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service.validation; 18 | 19 | import java.lang.annotation.Documented; 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | import javax.validation.Constraint; 26 | 27 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Constraint(validatedBy = PhoneValidator.class) 30 | @Documented 31 | public @interface PhoneValidation { 32 | 33 | } 34 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/service/validation/PhoneValidator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service.validation; 18 | 19 | import javax.validation.ConstraintValidator; 20 | import javax.validation.ConstraintValidatorContext; 21 | 22 | import com.google.i18n.phonenumbers.PhoneNumberUtil; 23 | 24 | /** 25 | * Validator that will validate phone numbers using google libphonenumber. 26 | */ 27 | public class PhoneValidator implements ConstraintValidator { 28 | 29 | @Override 30 | public void initialize(PhoneValidation validation) { 31 | } 32 | 33 | @Override 34 | public boolean isValid(String value, ConstraintValidatorContext context) { 35 | return PhoneNumberUtil.getInstance().isPossibleNumber(value, null) || isPossibleNumber(value); 36 | } 37 | 38 | /** 39 | * Custom implementation which only checks digits 40 | */ 41 | private boolean isPossibleNumber(String value) { 42 | try { 43 | Double.parseDouble(value); 44 | return true; 45 | } catch (NumberFormatException e) { 46 | return false; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/spring/ServiceCacheConfig.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.spring; 2 | 3 | import java.util.Arrays; 4 | 5 | import org.jboss.aerogear.unifiedpush.cassandra.dao.AliasDao; 6 | import org.jboss.aerogear.unifiedpush.cassandra.dao.DatabaseDao; 7 | import org.jboss.aerogear.unifiedpush.service.GenericVariantService; 8 | import org.jboss.aerogear.unifiedpush.service.PushApplicationService; 9 | import org.jboss.aerogear.unifiedpush.service.impl.spring.IKeycloakService; 10 | import org.springframework.cache.CacheManager; 11 | import org.springframework.cache.annotation.EnableCaching; 12 | import org.springframework.cache.caffeine.CaffeineCacheManager; 13 | import org.springframework.context.annotation.Bean; 14 | import org.springframework.context.annotation.Configuration; 15 | import org.springframework.context.annotation.Primary; 16 | 17 | import com.github.benmanes.caffeine.cache.CaffeineSpec; 18 | 19 | @Configuration 20 | @EnableCaching 21 | public class ServiceCacheConfig { 22 | @Bean 23 | @Primary 24 | public CacheManager cacheManager() { 25 | CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager(); 26 | caffeineCacheManager.setCaffeineSpec(CaffeineSpec.parse("maximumSize=100000,expireAfterAccess=600s")); 27 | caffeineCacheManager.setCacheNames(Arrays.asList(DatabaseDao.CACHE_NAME, AliasDao.CACHE_NAME, 28 | IKeycloakService.CACHE_NAME, GenericVariantService.CACHE_NAME, 29 | PushApplicationService.APPLICATION_CACHE_BY_ID, PushApplicationService.APPLICATION_CACHE_BY_VAR_ID, 30 | PushApplicationService.APPLICATION_CACHE_BY_NAME)); 31 | 32 | return caffeineCacheManager; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /service/src/main/java/org/jboss/aerogear/unifiedpush/spring/ServiceConfig.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.spring; 2 | 3 | import org.jboss.aerogear.unifiedpush.cassandra.CassandraConfig; 4 | import org.jboss.aerogear.unifiedpush.jpa.JPAConfig; 5 | import org.jboss.aerogear.unifiedpush.service.impl.AliasServiceImpl; 6 | import org.jboss.aerogear.unifiedpush.service.impl.spring.IConfigurationService; 7 | import org.jboss.aerogear.unifiedpush.service.metrics.IPushMessageMetricsService; 8 | import org.jboss.aerogear.unifiedpush.system.ConfigurationEnvironment; 9 | import org.springframework.context.annotation.ComponentScan; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.context.annotation.Import; 12 | 13 | @Configuration 14 | @Import({ ConfigurationEnvironment.class, ServiceCacheConfig.class, CassandraConfig.class, JPAConfig.class }) 15 | @ComponentScan(basePackageClasses = { AliasServiceImpl.class, IConfigurationService.class, 16 | IPushMessageMetricsService.class }) 17 | public class ServiceConfig { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /service/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /service/src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /service/src/main/resources/realm.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm": "REALM-ACCOUNT", 3 | "enabled": true, 4 | "accessTokenLifespan": 60, 5 | "accessCodeLifespan": 60, 6 | "accessCodeLifespanUserAction": 300, 7 | "ssoSessionIdleTimeout": 600, 8 | "ssoSessionMaxLifespan": 36000, 9 | "sslRequired": "external", 10 | "registrationAllowed": false, 11 | "social": false, 12 | "adminTheme": "aerobase", 13 | "accountTheme": "aerobase", 14 | "loginTheme": "aerobase", 15 | "emailTheme": "aerobase", 16 | "updateProfileOnInitialSocialLogin": false, 17 | "requiredCredentials": [ "password" ], 18 | "defaultRoles": [ "installation" ], 19 | "users" : [ 20 | { 21 | "username" : "admin", 22 | "enabled": false, 23 | "realmRoles": [ "admin" ], 24 | "applicationRoles": { 25 | "realm-management": [ "realm-admin" ], 26 | "account": [ "manage-account" ] 27 | } 28 | } 29 | ], 30 | "roles" : { 31 | "realm" : [ 32 | { 33 | "name": "admin", 34 | "description": "Administrator privileges" 35 | }, 36 | { 37 | "name": "installation", 38 | "description": "Device installation privileges" 39 | } 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /service/src/test/filtered-resources/default.properties: -------------------------------------------------------------------------------- 1 | aerogear.config.verification.enable_verification=false 2 | aerogear.config.verification.impl.class=org.jboss.aerogear.unifiedpush.service.sms.ClickatellSMSSender 3 | 4 | aerogear.config.oauth2.enable=false 5 | aerogear.config.oauth2.admin.username=admin 6 | aerogear.config.oauth2.admin.password=password 7 | 8 | aerogear.config.oauth2.keycloak.url=http://localhost/auth 9 | aerogear.config.oauth2.ups.admin.client=admin-cli 10 | aerogear.config.oauth2.ups.realm.name=master 11 | aerogear.config.oauth2.enforce.rooturl.protocol=https 12 | aerogear.config.oauth2.enforce.rooturl.domain=aerobase.io 13 | aerogear.config.oauth2.enforce.rooturl.seperator=. 14 | 15 | aerogear.config.cassandra.consistencylevel=ONE 16 | aerogear.config.cassandra.keyspace=unifiedpush_server 17 | aerogear.config.cassandra.contactpoints=127.0.0.1 18 | aerogear.config.cassandra.port=9142 19 | aerogear.config.cassandra.rpc_port=9171 20 | aerogear.config.cassandra.storage_port=7010 21 | aerogear.config.cassandra.ssl_storage_port=7011 22 | aerogear.config.cassandra.cql.init.timeout=60000 -------------------------------------------------------------------------------- /service/src/test/java/org/jboss/aerogear/unifiedpush/service/AbstractNoCassandraServiceTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service; 18 | 19 | import org.junit.runner.RunWith; 20 | import org.springframework.test.context.ActiveProfiles; 21 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 22 | 23 | @RunWith(SpringJUnit4ClassRunner.class) 24 | @ActiveProfiles(profiles = { "default" }) 25 | public abstract class AbstractNoCassandraServiceTest extends AbstractBaseServiceTest { 26 | 27 | @Override 28 | protected void specificSetup() { 29 | // TODO Auto-generated method stub 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /service/src/test/java/org/jboss/aerogear/unifiedpush/service/CassandraUnitTestClassExecutionListener.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service; 2 | 3 | import org.cassandraunit.spring.CassandraUnitDependencyInjectionIntegrationTestExecutionListener; 4 | import org.springframework.test.context.TestContext; 5 | 6 | public class CassandraUnitTestClassExecutionListener 7 | extends CassandraUnitDependencyInjectionIntegrationTestExecutionListener { 8 | 9 | @Override 10 | public void beforeTestClass(TestContext testContext) throws Exception { 11 | super.beforeTestClass(testContext); 12 | } 13 | 14 | @Override 15 | public void afterTestClass(TestContext testContext) throws Exception { 16 | try { 17 | super.cleanServer(); 18 | } catch (Exception e) { 19 | // TODO: ignore exception due to 20 | // https://github.com/jsevellec/cassandra-unit/issues/220 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /service/src/test/java/org/jboss/aerogear/unifiedpush/service/TestUtils.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service; 2 | 3 | import java.util.UUID; 4 | 5 | public class TestUtils { 6 | 7 | public static String generateFakedDeviceTokenString() { 8 | final StringBuilder sb = new StringBuilder(); 9 | sb.append(UUID.randomUUID().toString()); 10 | sb.append(UUID.randomUUID().toString()); 11 | sb.append(UUID.randomUUID().toString()); 12 | return sb.toString(); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /service/src/test/java/org/jboss/aerogear/unifiedpush/service/impl/health/PingTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JBoss, Home of Professional Open Source 3 | * Copyright Red Hat, Inc., and individual contributors. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.jboss.aerogear.unifiedpush.service.impl.health; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | import org.junit.Test; 22 | 23 | public class PingTest { 24 | 25 | @Test 26 | public void testIsReachable() throws Exception { 27 | //given 28 | String host = "google.com"; 29 | 30 | //when 31 | final boolean reachable = Ping.isReachable(host, 80); 32 | 33 | //then 34 | assertThat(reachable).isTrue(); 35 | } 36 | } -------------------------------------------------------------------------------- /service/src/test/java/org/jboss/aerogear/unifiedpush/service/spring/AccountNameMatcherTest.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.spring; 2 | 3 | import org.jboss.aerogear.unifiedpush.service.impl.spring.KeycloakServiceImpl.AccountNameMatcher; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | public class AccountNameMatcherTest { 8 | 9 | @Test 10 | public void testSpecialCherecters() { 11 | Assert.assertTrue(AccountNameMatcher.matches("yaniv_test@test.com").equals("yaniv-test-test-com")); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /service/src/test/java/org/jboss/aerogear/unifiedpush/service/spring/ConfigurationTest.java: -------------------------------------------------------------------------------- 1 | package org.jboss.aerogear.unifiedpush.service.spring; 2 | 3 | import org.jboss.aerogear.unifiedpush.system.ConfigurationEnvironment; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.test.context.ContextConfiguration; 9 | import org.springframework.test.context.TestExecutionListeners; 10 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 11 | import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; 12 | 13 | @RunWith(SpringJUnit4ClassRunner.class) 14 | @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class }) 15 | @ContextConfiguration(classes = { ConfigurationEnvironment.class }) 16 | public class ConfigurationTest { 17 | 18 | @Autowired 19 | private ConfigurationEnvironment configuration; 20 | 21 | @Test 22 | public void testDefaultConfigurationLoader() { 23 | Assert.assertTrue(configuration.isPortalMode()); 24 | } 25 | 26 | @Test 27 | public void testSystemPropertiesOverride() { 28 | System.setProperty(ConfigurationEnvironment.PROP_PORTAL_MODE, Boolean.FALSE.toString()); 29 | 30 | Assert.assertFalse(configuration.isPortalMode()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /service/src/test/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /service/src/test/resources/META-INF/db.properties: -------------------------------------------------------------------------------- 1 | # H2 connection string 2 | jdbcUrl=jdbc:h2:mem:unifiedpush;LOCK_TIMEOUT=10000 3 | 4 | dataSource.dataSource=true 5 | dataSource.prepStmtCacheSize=250 6 | dataSource.prepStmtCacheSqlLimit=2048 7 | dataSource.useServerPrepStmts=true 8 | 9 | # Maximum number of JDBC connections in the pool. Hibernate default: 100 10 | maximumPoolSize=100 11 | # Seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire. Default: 300 12 | idleTimeout=300 -------------------------------------------------------------------------------- /service/src/test/resources/META-INF/hibernate.properties: -------------------------------------------------------------------------------- 1 | hibernate.dialect=org.hibernate.dialect.H2Dialect 2 | hibernate.hbm2ddl.import_files=META-INF/test-data.sql 3 | hibernate.hbm2ddl.auto=create 4 | hibernate.show_sql=false 5 | hibernate.format_sql=false 6 | hibernate.transaction.flush_before_completion=true 7 | hibernate.id.new_generator_mappings=true -------------------------------------------------------------------------------- /service/src/test/resources/META-INF/test-data.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- H2 database query 3 | -- 4 | 5 | INSERT INTO push_application VALUES ('711c8b98-9c2c-4d94-abe7-ecff7145c015', NULL, 'admin', '1f73558f-d01b-48d7-9f6a-fc5d0ec6da51', 'DEFAULT', '7385c294-2003-4abf-83f6-29a27415326b'); 6 | 7 | INSERT INTO variant VALUES ('ios', '5ede4a1b-0277-4467-992c-02a7b307e555', NULL, 'admin', 'DEFAULT', '088a814a-ff2b-4acf-9091-5bcd0ccece16', 1, 'd3f54c25-c3ce-4999-b7a8-27dc9bb01364', '711c8b98-9c2c-4d94-abe7-ecff7145c015'); 8 | 9 | INSERT INTO ios_variant VALUES ('TBD123', 'TBD123', false, '5ede4a1b-0277-4467-992c-02a7b307e555'); 10 | 11 | 12 | -------------------------------------------------------------------------------- /service/src/test/resources/cert/certificate.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aerobase/unifiedpush-server/43430e1c3abaf62b331cbbeb6dd8036b81f3ca8a/service/src/test/resources/cert/certificate.p12 -------------------------------------------------------------------------------- /service/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ups-home-ui-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aerobase/unifiedpush-server/43430e1c3abaf62b331cbbeb6dd8036b81f3ca8a/ups-home-ui-screenshot.png -------------------------------------------------------------------------------- /ups-ui-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aerobase/unifiedpush-server/43430e1c3abaf62b331cbbeb6dd8036b81f3ca8a/ups-ui-screenshot.png --------------------------------------------------------------------------------