001    package org.kuali.common.deploy.spring;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    import java.util.Properties;
006    
007    import org.codehaus.plexus.util.StringUtils;
008    import org.kuali.common.deploy.DeployContext;
009    import org.kuali.common.deploy.Deployable;
010    import org.kuali.common.deploy.channel.spring.DefaultSecureChannelConfig;
011    import org.kuali.common.deploy.env.model.DeployEnvironment;
012    import org.kuali.common.deploy.env.spring.DefaultDeployEnvironmentConfig;
013    import org.kuali.common.deploy.env.spring.DeployEnvironmentConfig;
014    import org.kuali.common.util.PropertyUtils;
015    import org.kuali.common.util.maven.model.Artifact;
016    import org.kuali.common.util.nullify.NullUtils;
017    import org.kuali.common.util.secure.channel.SecureChannel;
018    import org.kuali.common.util.secure.channel.spring.SecureChannelConfig;
019    import org.kuali.common.util.spring.PropertySourceUtils;
020    import org.kuali.common.util.spring.env.EnvironmentService;
021    import org.kuali.common.util.spring.service.SpringServiceConfig;
022    import org.springframework.beans.factory.annotation.Autowired;
023    import org.springframework.context.annotation.Bean;
024    import org.springframework.context.annotation.Configuration;
025    import org.springframework.context.annotation.Import;
026    import org.springframework.core.env.ConfigurableEnvironment;
027    
028    import com.google.common.base.Optional;
029    
030    @Configuration
031    @Import({ SpringServiceConfig.class, DefaultDeployEnvironmentConfig.class, DefaultSecureChannelConfig.class })
032    public class DefaultDeployContextConfig implements DeployContextConfig {
033    
034            @Autowired
035            EnvironmentService env;
036    
037            @Autowired
038            ConfigurableEnvironment configurableEnvironment;
039    
040            @Autowired
041            DeployEnvironmentConfig deployEnvConfig;
042    
043            @Autowired
044            SecureChannelConfig channelConfig;
045    
046            @Override
047            @Bean
048            public DeployContext deployContext() {
049                    return getDeployContext();
050            }
051    
052            protected List<Deployable> getApplicationConfig() {
053                    Properties properties = PropertySourceUtils.getAllEnumerableProperties(configurableEnvironment);
054                    Properties configProperties = PropertyUtils.getProperties(properties, "kdo.config.*.local", null);
055                    List<String> keys = PropertyUtils.getSortedKeys(configProperties);
056                    List<Deployable> deployables = new ArrayList<Deployable>();
057                    for (String key : keys) {
058                            Deployable deployable = getApplicationConfig(key);
059                            if (deployable.isExists()) {
060                                    deployables.add(deployable);
061                            }
062                    }
063                    return deployables;
064            }
065    
066            protected Deployable getApplicationConfig(String localKey) {
067                    // kdo.config.1.local
068                    String[] tokens = StringUtils.split(localKey, ".");
069    
070                    // Should always be 4 tokens
071                    if (tokens.length != 4) {
072                            throw new IllegalStateException("Expected 4 tokens [" + localKey + "]");
073                    }
074    
075                    // Third token is a unique identifier for this config file
076                    String identifier = tokens[2];
077    
078                    // Assemble property keys
079                    String remoteKey = "kdo.config." + identifier + ".remote";
080                    String filterKey = "kdo.config." + identifier + ".filter";
081                    String requiredKey = "kdo.config." + identifier + ".required";
082    
083                    // Extract information using the property keys
084                    String local = env.getString(localKey);
085                    String remote = env.getString(remoteKey);
086                    boolean filter = env.getBoolean(filterKey, true); // Config files are filtered by default
087                    boolean required = env.getBoolean(requiredKey, true); // Config files are required by default
088    
089                    // Create a new deployable from the information we gathered from the environment
090                    return new Deployable.Builder(local, remote).filter(filter).required(required).build();
091            }
092    
093            // This isn't really optional because all supported vendor specific drivers are declared as dependencies in the KDO profile
094            // of the top level kuali pom, and thus must exist and be downloadable.
095            protected Optional<Artifact> getJdbcDriverArtifact() {
096                    Artifact driver = getVendorJdbcDriver();
097                    String groupId = env.getString("jdbc.driver.groupId", driver.getGroupId());
098                    String artifactId = env.getString("jdbc.driver.artifactId", driver.getArtifactId());
099                    String version = env.getString("jdbc.driver.version", driver.getVersion());
100                    Artifact artifact = new Artifact.Builder(groupId, artifactId, version).build();
101                    return Optional.of(artifact);
102            }
103    
104            // This isn't because all supported vendor specific drivers are declared as dependencies in the KDO profile
105            // of the top level kuali pom, and thus must exist and be downloadable.
106            protected Artifact getVendorJdbcDriver() {
107                    String vendor = env.getString("db.vendor");
108                    String groupIdKey = vendor + ".groupId";
109                    String artifactIdKey = vendor + ".artifactId";
110                    String versionKey = vendor + ".version";
111                    String groupId = env.getString(groupIdKey);
112                    String artifactId = env.getString(artifactIdKey);
113                    String version = env.getString(versionKey);
114                    return new Artifact.Builder(groupId, artifactId, version).build();
115            }
116    
117            protected Artifact getApplicationArtifact() {
118                    // TODO This only works because deploy.groupId is set inside the top level kuali-pom
119                    // TODO This won't work on process not launched from the Maven CLI
120                    // TODO Come up with something better here
121                    String groupId = env.getString("deploy.groupId");
122                    String artifactId = env.getString("project.artifactId");
123                    String version = env.getString("project.version");
124                    String classifier = env.getString("project.classifier", NullUtils.NONE);
125                    String type = env.getString("project.packaging");
126                    return new Artifact.Builder(groupId, artifactId, version).classifier(classifier).type(type).build();
127            }
128    
129            protected DeployContext getDeployContext() {
130                    Optional<Artifact> jdbcDriver = getJdbcDriverArtifact();
131                    Artifact application = getApplicationArtifact();
132                    List<Deployable> configFiles = getApplicationConfig();
133                    SecureChannel channel = channelConfig.secureChannel();
134                    DeployEnvironment environment = deployEnvConfig.deployEnvironment();
135                    return new DeployContext.Builder(environment, channel, application).jdbcDriver(jdbcDriver).configFiles(configFiles).build();
136            }
137    
138    }