}
if (Strings.isNullOrBlank(parentProfileName)) {
parentProfileName = replicated ? MQ_PROFILE_REPLICATED : MQ_PROFILE_BASE;
}
Profile parentProfile = version.getRequiredProfile(parentProfileName);
if (brokerName == null || profileId == null) {
return parentProfile;
}
String pidName = getBrokerPID(brokerName);
// lets check we have a config value
ProfileBuilder builder;
// create a profile if it doesn't exist
Map<String, String> config = null;
boolean create = !version.hasProfile(profileId);
if (create) {
builder = ProfileBuilder.Factory.create(versionId, profileId);
if (parentProfile != null) {
builder.addParent(parentProfile.getId());
}
} else {
Profile profile = version.getRequiredProfile(profileId);
builder = ProfileBuilder.Factory.createFrom(profile);
config = new HashMap<>(builder.getConfiguration(pidName));
}
Map<String, String> parentProfileConfig = parentProfile.getConfiguration(MQ_PID_TEMPLATE);
if (config == null) {
config = new HashMap<>(parentProfileConfig);
}
if (configs != null && "true".equals(configs.get("ssl"))) {
// Only generate the keystore file if it does not exist.
// [TOOD] Fix direct data access! This should be part of the ProfileBuilder
byte[] keystore = builder.getFileConfiguration("keystore.jks");
if( keystore==null ) {
try {
String host = configs.get("keystore.cn");
if( host == null ) {
host = configs.get(GROUP);
if( host == null ) {
host = "localhost";
}
configs.put("keystore.cn", host);
}
String password = configs.get("keystore.password");
if( password == null ) {
password = generatePassword(8);
configs.put("keystore.password", password);
}
File keystoreFile = io.fabric8.utils.Files.createTempFile(runtimeProperties.getDataPath());
keystoreFile.delete();
LOG.info("Generating ssl keystore...");
int rc = system("keytool", "-genkey",
"-storetype", "JKS",
"-storepass", password,
"-keystore", keystoreFile.getCanonicalPath(),
"-keypass", password,
"-alias", host,
"-keyalg", "RSA",
"-keysize", "4096",
"-dname", String.format("cn=%s", host),
"-validity", "3650");
if(rc!=0) {
throw new IOException("keytool failed with exit code: "+rc);
}
keystore = Files.readBytes(keystoreFile);
keystoreFile.delete();
LOG.info("Keystore generated");
builder.addFileConfiguration("keystore.jks", keystore);
configs.put("keystore.file", "profile:keystore.jks");
} catch (IOException e) {
LOG.info("Failed to generate keystore.jks: "+e, e);
}
}
// [TOOD] Fix direct data access! This should be part of the ProfileBuilder
byte[] truststore = builder.getFileConfiguration("truststore.jks");
if (truststore == null) {
try {
String password = configs.get("truststore.password");
if( password == null ) {
password = configs.get("keystore.password");
configs.put("truststore.password", password);
}
File keystoreFile = io.fabric8.utils.Files.createTempFile(runtimeProperties.getDataPath());
Files.writeToFile(keystoreFile, keystore);
File certFile = io.fabric8.utils.Files.createTempFile(runtimeProperties.getDataPath());
certFile.delete();
LOG.info("Exporting broker certificate to create truststore.jks");
int rc = system("keytool", "-exportcert", "-rfc",
"-keystore", keystoreFile.getCanonicalPath(),
"-storepass", configs.get("keystore.password"),
"-alias", configs.get("keystore.cn"),
"--file", certFile.getCanonicalPath());
keystoreFile.delete();
if(rc!=0) {
throw new IOException("keytool failed with exit code: "+rc);
}
LOG.info("Creating truststore.jks");
File truststoreFile = io.fabric8.utils.Files.createTempFile(runtimeProperties.getDataPath());
truststoreFile.delete();
rc = system("keytool", "-importcert", "-noprompt",
"-keystore", truststoreFile.getCanonicalPath(),
"-storepass", password,
"--file", certFile.getCanonicalPath());
certFile.delete();
if(rc!=0) {
throw new IOException("keytool failed with exit code: "+rc);
}
truststore = Files.readBytes(truststoreFile);
truststoreFile.delete();
builder.addFileConfiguration("truststore.jks", truststore);
configs.put("truststore.file", "profile:truststore.jks");
} catch (IOException e) {
LOG.info("Failed to generate truststore.jks due: " + e.getMessage(), e);
}
}
}
config.put("broker-name", brokerName);
if (configs != null) {
config.putAll(configs);
}
// lets check we've a bunch of config values inherited from the template
String[] propertiesToDefault = { CONFIG_URL, STANDBY_POOL, CONNECTORS };
for (String key : propertiesToDefault) {
if (config.get(key) == null) {
String defaultValue = parentProfileConfig.get(key);
if (Strings.isNotBlank(defaultValue)) {
config.put(key, defaultValue);
}
}
}
builder.addConfiguration(pidName, config);
Profile profile = builder.getProfile();
return create ? profileService.createProfile(profile) : profileService.updateProfile(profile);
}