1 package net.sumaris.core.service.technical;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.google.common.base.Preconditions;
26 import net.sumaris.core.config.SumarisConfiguration;
27 import net.sumaris.core.config.SumarisConfigurationOption;
28 import net.sumaris.core.dao.schema.DatabaseSchemaDao;
29 import net.sumaris.core.dao.technical.SoftwareDao;
30 import net.sumaris.core.exception.VersionNotFoundException;
31 import net.sumaris.core.vo.technical.SoftwareVO;
32 import org.apache.commons.collections4.MapUtils;
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.nuiton.config.ApplicationConfig;
36 import org.nuiton.config.ApplicationConfigHelper;
37 import org.nuiton.config.ApplicationConfigProvider;
38 import org.nuiton.version.Version;
39 import org.nuiton.version.VersionBuilder;
40 import org.springframework.beans.factory.annotation.Autowired;
41 import org.springframework.context.annotation.Bean;
42 import org.springframework.stereotype.Component;
43
44 import javax.annotation.PostConstruct;
45 import java.io.BufferedReader;
46 import java.io.InputStreamReader;
47 import java.net.URL;
48 import java.util.Optional;
49 import java.util.Set;
50 import java.util.stream.Collectors;
51 import java.util.stream.Stream;
52
53
54 @Component("softwareService")
55 public class SoftwareServiceImpl implements SoftwareService {
56
57 private static final Log log = LogFactory.getLog(SoftwareServiceImpl.class);
58
59 @Autowired
60 private SoftwareDao dao;
61
62 @Autowired
63 private DatabaseSchemaDao databaseSchemaDao;
64
65 private String defaultSoftwareLabel;
66
67
68 public SoftwareServiceImpl(SumarisConfiguration configuration) {
69 this.defaultSoftwareLabel = configuration.getAppName();
70 Preconditions.checkNotNull(defaultSoftwareLabel);
71 }
72
73 @PostConstruct
74 protected void afterPropertiesSet() {
75
76 loadConfigurationFromDatabase();
77 }
78
79 @Override
80 public SoftwareVO getDefault() {
81 return dao.get(defaultSoftwareLabel);
82 }
83
84 @Override
85 public SoftwareVO get(String label) {
86 Preconditions.checkNotNull(label);
87
88 return dao.get(label);
89 }
90
91 @Override
92 public SoftwareVO"../../../../../net/sumaris/core/vo/technical/SoftwareVO.html#SoftwareVO">SoftwareVO save(SoftwareVO source) {
93 Preconditions.checkNotNull(source);
94 Preconditions.checkNotNull(source.getLabel());
95
96 return dao.save(source);
97 }
98
99
100
101
102
103
104 @Bean
105 private Optional<String> whatsMyIp() {
106
107 try {
108 URL whatismyip = new URL("http://checkip.amazonaws.com");
109 BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream()));
110 return Optional.of(in.readLine());
111 } catch (Exception e) {
112 return Optional.empty();
113 }
114 }
115
116 protected void loadConfigurationFromDatabase() {
117
118 try {
119 Version dbVersion = databaseSchemaDao.getSchemaVersion();
120 Version minVersion = VersionBuilder.create("0.9.5").build();
121
122
123 if (dbVersion == null || minVersion.after(dbVersion)) {
124 log.warn(String.format("Skipping configuration override from database (expected min schema version {%s})", minVersion.toString()));
125 return;
126 }
127 } catch(VersionNotFoundException e) {
128
129 }
130
131 ApplicationConfig appConfig = SumarisConfiguration.getInstance().getApplicationConfig();
132
133 SoftwareVO software = getDefault();
134 if (software == null) {
135 log.info(String.format("No configuration for {%s} found in database. to enable configuration override from database, make sure to set the option '%s' to an existing row of the table SOFTWARE (column LABEL).", defaultSoftwareLabel, SumarisConfigurationOption.APP_NAME.getKey()));
136 }
137 else if (MapUtils.isNotEmpty(software.getProperties())) {
138 log.info(String.format("Overriding configuration options, using those found in database for {%s}", defaultSoftwareLabel));
139
140
141 Set<ApplicationConfigProvider> providers =
142 ApplicationConfigHelper.getProviders(null,
143 null,
144 null,
145 true);
146 Set<String> optionKeys = providers.stream().flatMap(p -> Stream.of(p.getOptions()))
147 .map(o -> o.getKey()).collect(Collectors.toSet());
148 Set<String> transientOptionKeys = providers.stream().flatMap(p -> Stream.of(p.getOptions()))
149 .filter(o -> o.isTransient())
150 .map(o -> o.getKey()).collect(Collectors.toSet());
151
152 software.getProperties().entrySet()
153 .forEach(entry -> {
154 if (!optionKeys.contains(entry.getKey())) {
155 if (log.isDebugEnabled()) log.debug(String.format(" - Skipping unknown configuration option {%s=%s} found in database for {%s}.", entry.getKey(), entry.getValue(), defaultSoftwareLabel));
156 }
157 else if (transientOptionKeys.contains(entry.getKey())) {
158 if (log.isDebugEnabled()) log.debug(String.format(" - Skipping transient configuration option {%s=%s} found in database for {%s}.", entry.getKey(), entry.getValue(), defaultSoftwareLabel));
159 }
160 else {
161 if (log.isDebugEnabled()) log.debug(String.format(" - Applying option {%s=%s}", entry.getKey(), entry.getValue()));
162
163 appConfig.setOption(entry.getKey(), entry.getValue());
164 }
165 });
166 }
167 }
168
169 }