Skip to content

Commit fcf8809

Browse files
author
blackopsdev
committed
multiple applications support
1 parent dee1dfb commit fcf8809

1 file changed

Lines changed: 112 additions & 42 deletions

File tree

src/main/java/com/stackify/api/common/AppIdentityService.java

Lines changed: 112 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package com.stackify.api.common;
1717

1818
import java.io.IOException;
19+
import java.util.Hashtable;
20+
import java.util.Map;
1921

2022
import org.slf4j.Logger;
2123
import org.slf4j.LoggerFactory;
@@ -44,27 +46,22 @@ public class AppIdentityService {
4446
* Five minutes (in milliseconds)
4547
*/
4648
private static long FIVE_MINUTES_MILLIS = 300000;
47-
48-
/**
49-
* Timestamp of the last query
50-
*/
51-
private long lastQuery = 0;
52-
49+
5350
/**
54-
* The cached app identity
51+
* Map<ApplicationName, AppIdentityState> The cached app identity
5552
*/
56-
private Optional<AppIdentity> appIdentity = Optional.absent();
57-
53+
private Map<String, AppIdentityState> applicationIdentityCache = new Hashtable<String, AppIdentityState>();
54+
5855
/**
5956
* The API configuration
6057
*/
61-
private final ApiConfiguration apiConfig;
58+
private final ApiConfiguration defaultApiConfig;
6259

6360
/**
6461
* Jackson object mapper
6562
*/
6663
private final ObjectMapper objectMapper;
67-
64+
6865
/**
6966
* Constructor
7067
* @param apiConfig The API configuration
@@ -73,55 +70,128 @@ public class AppIdentityService {
7370
public AppIdentityService(final ApiConfiguration apiConfig, final ObjectMapper objectMapper) {
7471
Preconditions.checkNotNull(apiConfig);
7572
Preconditions.checkNotNull(objectMapper);
76-
77-
this.apiConfig = apiConfig;
73+
74+
this.defaultApiConfig = apiConfig;
7875
this.objectMapper = objectMapper;
7976
}
80-
77+
78+
private boolean isCached(final String applicationName) {
79+
Preconditions.checkNotNull(applicationName);
80+
return applicationIdentityCache.containsKey(applicationName);
81+
}
82+
8183
/**
8284
* Retrieves the application identity given the environment details
8385
* @return The application identity
8486
*/
85-
public Optional<AppIdentity> getAppIdentity() {
86-
if (!appIdentity.isPresent()) {
87-
long currentTimeMillis = System.currentTimeMillis();
88-
89-
if (lastQuery + FIVE_MINUTES_MILLIS < currentTimeMillis) {
90-
try {
91-
lastQuery = currentTimeMillis;
92-
appIdentity = Optional.fromNullable(identifyApp());
93-
LOGGER.debug("Application identity: {}", appIdentity.get());
94-
} catch (Throwable t) {
95-
LOGGER.info("Unable to determine application identity", t);
96-
}
87+
private Optional<AppIdentity> getAppIdentity(ApiConfiguration apiConfig) {
88+
final String applicationName = apiConfig.getApplication();
89+
90+
if (applicationName == null)
91+
return Optional.absent();
92+
93+
// new state with current timestamp
94+
final AppIdentityState state = new AppIdentityState();
95+
96+
final long now = System.currentTimeMillis();
97+
98+
if (state.lastModified() + FIVE_MINUTES_MILLIS < now) {
99+
try {
100+
final AppIdentity identity = identifyApp(apiConfig);
101+
// Obtain AppIdentity for current app
102+
applicationIdentityCache.put(
103+
applicationName, state.updateAppIdentity(identity)
104+
);
105+
106+
LOGGER.debug("Application identity: {}", identity);
107+
108+
} catch (Throwable t) {
109+
LOGGER.info("Unable to determine application identity", t);
97110
}
98111
}
99-
100-
return appIdentity;
112+
113+
return applicationIdentityCache.get(apiConfig.getApplication()).getAppIdentity();
101114
}
102-
115+
116+
117+
118+
public Optional<AppIdentity> getAppIdentity(final String applicationName) {
119+
if (isCached(applicationName)) {
120+
return applicationIdentityCache.get(applicationName).getAppIdentity();
121+
122+
} else {
123+
// use existing apiConfig, with new application name
124+
final ApiConfiguration updatedApiConfig = defaultApiConfig.toBuilder().application(applicationName).build();
125+
return getAppIdentity(updatedApiConfig);
126+
}
127+
}
128+
129+
130+
public Optional<AppIdentity> getAppIdentity() {
131+
return getAppIdentity(defaultApiConfig);
132+
}
133+
103134
/**
104135
* Retrieves the application identity given the environment details
105136
* @return The application identity
106137
* @throws IOException
107-
* @throws HttpException
138+
* @throws HttpException
108139
*/
109-
private AppIdentity identifyApp() throws IOException, HttpException {
110-
140+
private AppIdentity identifyApp(ApiConfiguration apiConfig) throws IOException, HttpException {
111141
// convert to json bytes
112-
113142
byte[] jsonBytes = objectMapper.writer().writeValueAsBytes(apiConfig.getEnvDetail());
114-
143+
115144
// post to stackify
116-
117-
HttpClient httpClient = new HttpClient(apiConfig);
118-
String responseString = httpClient.post("/Metrics/IdentifyApp", jsonBytes);
119-
145+
final HttpClient httpClient = new HttpClient(apiConfig);
146+
final String responseString = httpClient.post("/Metrics/IdentifyApp", jsonBytes);
147+
120148
// deserialize the response and return the app identity
121-
122149
ObjectReader jsonReader = objectMapper.reader(new TypeReference<AppIdentity>(){});
123-
AppIdentity appIdentity = jsonReader.readValue(responseString);
124-
125-
return appIdentity;
150+
return jsonReader.readValue(responseString);
151+
}
152+
153+
/**
154+
* This class contains appIdentity and it's modification date
155+
*/
156+
private class AppIdentityState {
157+
158+
private Optional<AppIdentity> mayBeAppIdentity = Optional.absent();
159+
private long lastQueryTimeStamp;
160+
161+
public AppIdentityState() {
162+
this.lastQueryTimeStamp = 0;
163+
this.mayBeAppIdentity = Optional.absent();
164+
}
165+
166+
public AppIdentityState(final AppIdentity appIdentity) {
167+
this.touch();
168+
this.mayBeAppIdentity = Optional.fromNullable(appIdentity);
169+
}
170+
171+
public AppIdentityState(final AppIdentity appIdentity, long timestamp) {
172+
this.lastQueryTimeStamp = timestamp;
173+
this.mayBeAppIdentity = Optional.fromNullable(appIdentity);
174+
}
175+
176+
public final AppIdentityState updateAppIdentity(final AppIdentity appIdentity) {
177+
mayBeAppIdentity = Optional.fromNullable(appIdentity);
178+
return this;
179+
}
180+
181+
public final Optional<AppIdentity> getAppIdentity() {
182+
this.touch();
183+
return mayBeAppIdentity;
184+
}
185+
186+
public final long lastModified() {
187+
return lastQueryTimeStamp;
188+
}
189+
190+
/**
191+
* Changes last modified date
192+
*/
193+
public final void touch() {
194+
this.lastQueryTimeStamp = System.currentTimeMillis();
195+
}
126196
}
127197
}

0 commit comments

Comments
 (0)