Add improvements to Google API token generation in FCM

master
Pahansith Gunathilake 5 months ago
parent aafa824f08
commit b1d3503e8b

@ -22,6 +22,7 @@ import com.google.gson.JsonObject;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager; import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager;
import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.ContextMetadata; import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.ContextMetadata;
import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.PushNotificationConfiguration; import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.PushNotificationConfiguration;
import io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.util.FCMUtil;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.Device;
@ -53,12 +54,7 @@ public class FCMNotificationStrategy implements NotificationStrategy {
private static final int TIME_TO_LIVE = 2419199; // 1 second less than 28 days private static final int TIME_TO_LIVE = 2419199; // 1 second less than 28 days
private static final int HTTP_STATUS_CODE_OK = 200; private static final int HTTP_STATUS_CODE_OK = 200;
private final PushNotificationConfig config; private final PushNotificationConfig config;
private static final String FCM_SERVICE_ACCOUNT_PATH = CarbonUtils.getCarbonHome() + File.separator +
"repository" + File.separator + "resources" + File.separator + "service-account.json";
private static final String[] FCM_SCOPES = { "https://www.googleapis.com/auth/firebase.messaging" };
private static final String FCM_ENDPOINT_KEY = "FCM_SERVER_ENDPOINT"; private static final String FCM_ENDPOINT_KEY = "FCM_SERVER_ENDPOINT";
private Properties contextMetadataProperties;
private volatile GoogleCredentials defaultApplication;
public FCMNotificationStrategy(PushNotificationConfig config) { public FCMNotificationStrategy(PushNotificationConfig config) {
this.config = config; this.config = config;
@ -66,8 +62,7 @@ public class FCMNotificationStrategy implements NotificationStrategy {
@Override @Override
public void init() { public void init() {
initContextConfigs();
initDefaultOAuthApplication();
} }
@Override @Override
@ -77,8 +72,8 @@ public class FCMNotificationStrategy implements NotificationStrategy {
Device device = FCMDataHolder.getInstance().getDeviceManagementProviderService() Device device = FCMDataHolder.getInstance().getDeviceManagementProviderService()
.getDeviceWithTypeProperties(ctx.getDeviceId()); .getDeviceWithTypeProperties(ctx.getDeviceId());
if(device.getProperties() != null && getFCMToken(device.getProperties()) != null) { if(device.getProperties() != null && getFCMToken(device.getProperties()) != null) {
defaultApplication.refresh(); FCMUtil.getInstance().getDefaultApplication().refresh();
sendWakeUpCall(defaultApplication.getAccessToken().getTokenValue(), sendWakeUpCall(FCMUtil.getInstance().getDefaultApplication().getAccessToken().getTokenValue(),
getFCMToken(device.getProperties())); getFCMToken(device.getProperties()));
} }
} else { } else {
@ -94,43 +89,14 @@ public class FCMNotificationStrategy implements NotificationStrategy {
} }
} }
private void initDefaultOAuthApplication() {
if (defaultApplication == null) {
synchronized (FCMNotificationStrategy.class) {
if (defaultApplication == null) {
Path serviceAccountPath = Paths.get(FCM_SERVICE_ACCOUNT_PATH);
try {
this.defaultApplication = GoogleCredentials.
fromStream(Files.newInputStream(serviceAccountPath)).
createScoped(FCM_SCOPES);
} catch (IOException e) {
log.error("Fail to initialize default OAuth application for FCM communication");
throw new IllegalStateException(e);
}
}
}
}
}
private void initContextConfigs() {
PushNotificationConfiguration pushNotificationConfiguration = DeviceConfigurationManager.getInstance().
getDeviceManagementConfig().getPushNotificationConfiguration();
List<ContextMetadata> contextMetadata = pushNotificationConfiguration.getContextMetadata();
Properties properties = new Properties();
if (contextMetadata != null) {
for (ContextMetadata metadata : contextMetadata) {
properties.setProperty(metadata.getKey(), metadata.getValue());
}
}
contextMetadataProperties = properties;
}
private void sendWakeUpCall(String accessToken, String registrationId) throws IOException, private void sendWakeUpCall(String accessToken, String registrationId) throws IOException,
PushNotificationExecutionFailedException { PushNotificationExecutionFailedException {
OutputStream os = null; OutputStream os = null;
HttpURLConnection conn = null; HttpURLConnection conn = null;
String fcmServerEndpoint = contextMetadataProperties.getProperty(FCM_ENDPOINT_KEY); String fcmServerEndpoint = FCMUtil.getInstance().getContextMetadataProperties().getProperty(FCM_ENDPOINT_KEY);
if(fcmServerEndpoint == null) { if(fcmServerEndpoint == null) {
String msg = "Encountered configuration issue. " + FCM_ENDPOINT_KEY + " is not defined"; String msg = "Encountered configuration issue. " + FCM_ENDPOINT_KEY + " is not defined";
log.error(msg); log.error(msg);

@ -0,0 +1,80 @@
package io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.util;
import com.google.auth.oauth2.GoogleCredentials;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager;
import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.ContextMetadata;
import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.PushNotificationConfiguration;
import io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.FCMNotificationStrategy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Properties;
public class FCMUtil {
private static final Log log = LogFactory.getLog(FCMUtil.class);
private static volatile FCMUtil instance;
private static GoogleCredentials defaultApplication;
private static final String FCM_SERVICE_ACCOUNT_PATH = CarbonUtils.getCarbonHome() + File.separator +
"repository" + File.separator + "resources" + File.separator + "service-account.json";
private static final String[] FCM_SCOPES = { "https://www.googleapis.com/auth/firebase.messaging" };
private Properties contextMetadataProperties;
private FCMUtil() {
initContextConfigs();
initDefaultOAuthApplication();
}
private void initDefaultOAuthApplication() {
if (defaultApplication == null) {
Path serviceAccountPath = Paths.get(FCM_SERVICE_ACCOUNT_PATH);
try {
defaultApplication = GoogleCredentials.
fromStream(Files.newInputStream(serviceAccountPath)).
createScoped(FCM_SCOPES);
} catch (IOException e) {
log.error("Fail to initialize default OAuth application for FCM communication");
throw new IllegalStateException(e);
}
}
}
private void initContextConfigs() {
PushNotificationConfiguration pushNotificationConfiguration = DeviceConfigurationManager.getInstance().
getDeviceManagementConfig().getPushNotificationConfiguration();
List<ContextMetadata> contextMetadata = pushNotificationConfiguration.getContextMetadata();
Properties properties = new Properties();
if (contextMetadata != null) {
for (ContextMetadata metadata : contextMetadata) {
properties.setProperty(metadata.getKey(), metadata.getValue());
}
}
contextMetadataProperties = properties;
}
public static FCMUtil getInstance() {
if (instance == null) {
synchronized (FCMUtil.class) {
if (instance == null) {
instance = new FCMUtil();
}
}
}
return instance;
}
public GoogleCredentials getDefaultApplication() {
return defaultApplication;
}
public Properties getContextMetadataProperties() {
return contextMetadataProperties;
}
}
Loading…
Cancel
Save