/*
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.apache.geode.tools.pulse.internal.data;
import org.apache.geode.tools.pulse.internal.log.PulseLogWriter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import java.net.ConnectException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.TimeUnit;
/**
* A Singleton instance of the memory cache for clusters.
*
* @since GemFire version 7.0.Beta 2012-09-23
*/
public class Repository {
private PulseLogWriter LOGGER;
private static Repository instance = new Repository();
private HashMap<String, Cluster> clusterMap = new HashMap<String, Cluster>();
private Boolean jmxUseLocator;
private String jmxHost;
private String jmxPort;
private String jmxUserName;
private String jmxUserPassword;
private Boolean isEmbeddedMode;
private boolean useSSLLocator = false;
private boolean useSSLManager = false;
private boolean useGemFireCredentials = false;
private String pulseWebAppUrl;
Locale locale =
new Locale(PulseConstants.APPLICATION_LANGUAGE, PulseConstants.APPLICATION_COUNTRY);
private ResourceBundle resourceBundle =
ResourceBundle.getBundle(PulseConstants.LOG_MESSAGES_FILE, locale);
private PulseConfig pulseConfig = new PulseConfig();
private Repository() {
}
public static Repository get() {
return instance;
}
public Boolean getJmxUseLocator() {
return this.jmxUseLocator;
}
public void setJmxUseLocator(Boolean jmxUseLocator) {
this.jmxUseLocator = jmxUseLocator;
}
public String getJmxHost() {
return this.jmxHost;
}
public void setJmxHost(String jmxHost) {
this.jmxHost = jmxHost;
}
public String getJmxPort() {
return this.jmxPort;
}
public void setJmxPort(String jmxPort) {
this.jmxPort = jmxPort;
}
public String getJmxUserName() {
return this.jmxUserName;
}
public void setJmxUserName(String jmxUserName) {
this.jmxUserName = jmxUserName;
}
public String getJmxUserPassword() {
return this.jmxUserPassword;
}
public void setJmxUserPassword(String jmxUserPassword) {
this.jmxUserPassword = jmxUserPassword;
}
public Boolean getIsEmbeddedMode() {
return this.isEmbeddedMode;
}
public void setIsEmbeddedMode(Boolean isEmbeddedMode) {
this.isEmbeddedMode = isEmbeddedMode;
}
public boolean isUseSSLLocator() {
return useSSLLocator;
}
public void setUseSSLLocator(boolean useSSLLocator) {
this.useSSLLocator = useSSLLocator;
}
public boolean isUseSSLManager() {
return useSSLManager;
}
public void setUseSSLManager(boolean useSSLManager) {
this.useSSLManager = useSSLManager;
}
public String getPulseWebAppUrl() {
return this.pulseWebAppUrl;
}
public void setPulseWebAppUrl(String pulseWebAppUrl) {
this.pulseWebAppUrl = pulseWebAppUrl;
}
public PulseConfig getPulseConfig() {
return this.pulseConfig;
}
public void setPulseConfig(PulseConfig pulseConfig) {
this.pulseConfig = pulseConfig;
}
/**
* we're maintaining a 1:1 mapping between webapp and cluster, there is no need for a map of
* clusters based on the host and port We are using this clusterMap to maintain cluster for
* different users now. For a single-user connection to gemfire JMX, we will use the default
* username/password in the pulse.properties (# JMX User Properties ) pulse.jmxUserName=admin
* pulse.jmxUserPassword=admin
*
* But for multi-user connections to gemfireJMX, i.e pulse that uses gemfire integrated security,
* we will need to get the username form the context
*/
public Cluster getCluster() {
String username = null;
String password = null;
if (useGemFireCredentials) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
username = auth.getName();
password = (String) auth.getCredentials();
}
} else {
username = this.jmxUserName;
password = this.jmxUserPassword;
}
return this.getCluster(username, password);
}
public Cluster getCluster(String username, String password) {
synchronized (this.clusterMap) {
String key = username;
Cluster data = this.clusterMap.get(key);
LOGGER = PulseLogWriter.getLogger();
if (data == null) {
try {
if (LOGGER.infoEnabled()) {
LOGGER.info(resourceBundle.getString("LOG_MSG_CREATE_NEW_THREAD") + " : " + key);
}
data = new Cluster(this.jmxHost, this.jmxPort, username, password);
// Assign name to thread created
data.setName(
PulseConstants.APP_NAME + "-" + this.jmxHost + ":" + this.jmxPort + ":" + username);
// Start Thread
data.start();
data.waitForInitialization(15, TimeUnit.SECONDS);
this.clusterMap.put(key, data);
} catch (ConnectException | InterruptedException e) {
data = null;
if (LOGGER.fineEnabled()) {
LOGGER.fine(e.getMessage());
}
}
} else {
data.setJmxUserPassword(password);
}
return data;
}
}
private String getClusterKey(String host, String port) {
return host + ":" + port;
}
// This method is used to remove all cluster threads
public void removeAllClusters() {
Iterator<Map.Entry<String, Cluster>> iter = clusterMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Cluster> entry = iter.next();
Cluster c = entry.getValue();
String clusterKey = entry.getKey();
c.stopThread();
iter.remove();
if (LOGGER.infoEnabled()) {
LOGGER.info(
resourceBundle.getString("LOG_MSG_REMOVE_THREAD") + " : " + clusterKey.toString());
}
}
}
public ResourceBundle getResourceBundle() {
return this.resourceBundle;
}
public boolean isUseGemFireCredentials() {
return useGemFireCredentials;
}
public void setUseGemFireCredentials(boolean useGemFireCredentials) {
this.useGemFireCredentials = useGemFireCredentials;
}
}