introduces external server address alias config-property
This commit is contained in:
parent
70c1c09432
commit
9b105ab476
4 changed files with 85 additions and 6 deletions
|
@ -10,9 +10,14 @@ package ch.ethz.seb.sebserver.webservice;
|
|||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -26,6 +31,8 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
|||
@WebServiceProfile
|
||||
public class WebserviceInfo {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WebserviceInfo.class);
|
||||
|
||||
private static final String WEB_SERVICE_TEST_PROPERTY = "sebserver.test.property";
|
||||
private static final String WEB_SERVICE_SERVER_NAME_KEY = "sebserver.webservice.http.server.name";
|
||||
private static final String WEB_SERVICE_HTTP_SCHEME_KEY = "sebserver.webservice.http.scheme";
|
||||
|
@ -33,6 +40,7 @@ public class WebserviceInfo {
|
|||
private static final String WEB_SERVICE_SERVER_PORT_KEY = "server.port";
|
||||
private static final String WEB_SERVICE_EXAM_API_DISCOVERY_ENDPOINT_KEY =
|
||||
"sebserver.webservice.api.exam.endpoint.discovery";
|
||||
private static final String WEB_SERVICE_EXTERNAL_ADDRESS_ALIAS = "sebserver.webservice.lms.address.alias";
|
||||
|
||||
private final String testProperty;
|
||||
private final String httpScheme;
|
||||
|
@ -42,9 +50,10 @@ public class WebserviceInfo {
|
|||
private final String discoveryEndpoint;
|
||||
|
||||
private final String serverURLPrefix;
|
||||
|
||||
private final boolean isDistributed;
|
||||
|
||||
private Map<String, String> externalAddressAlias;
|
||||
|
||||
public WebserviceInfo(final Environment environment) {
|
||||
this.testProperty = environment.getProperty(WEB_SERVICE_TEST_PROPERTY, "NOT_AVAILABLE");
|
||||
this.httpScheme = environment.getRequiredProperty(WEB_SERVICE_HTTP_SCHEME_KEY);
|
||||
|
@ -64,6 +73,25 @@ public class WebserviceInfo {
|
|||
this.isDistributed = BooleanUtils.toBoolean(environment.getProperty(
|
||||
"sebserver.webservice.distributed",
|
||||
Constants.FALSE_STRING));
|
||||
|
||||
final String addressAlias = environment.getProperty(WEB_SERVICE_EXTERNAL_ADDRESS_ALIAS, "");
|
||||
if (StringUtils.isNotBlank(addressAlias)) {
|
||||
try {
|
||||
final String[] aliass = StringUtils.split(addressAlias, Constants.LIST_SEPARATOR);
|
||||
final Map<String, String> mapping = new LinkedHashMap<>();
|
||||
for (final String alias : aliass) {
|
||||
final String[] nameValue =
|
||||
StringUtils.split(alias, Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR);
|
||||
mapping.put(nameValue[0], nameValue[1]);
|
||||
}
|
||||
this.externalAddressAlias = Collections.unmodifiableMap(mapping);
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to parse sebserver.webservice.lms.address.alias: ", e);
|
||||
this.externalAddressAlias = Collections.emptyMap();
|
||||
}
|
||||
} else {
|
||||
this.externalAddressAlias = Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
public String getTestProperty() {
|
||||
|
@ -132,6 +160,20 @@ public class WebserviceInfo {
|
|||
return this.isDistributed;
|
||||
}
|
||||
|
||||
public Map<String, String> getExternalAddressAlias() {
|
||||
return this.externalAddressAlias;
|
||||
}
|
||||
|
||||
public String getExternalAddressAlias(final String internalAddress) {
|
||||
return this.externalAddressAlias
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> internalAddress.contains(entry.getKey()))
|
||||
.findFirst()
|
||||
.map(entry -> entry.getValue())
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
@ -147,6 +189,8 @@ public class WebserviceInfo {
|
|||
builder.append(this.serverPort);
|
||||
builder.append(", discoveryEndpoint=");
|
||||
builder.append(this.discoveryEndpoint);
|
||||
builder.append(", externalAddressAlias=");
|
||||
builder.append(this.externalAddressAlias);
|
||||
builder.append(", serverURLPrefix=");
|
||||
builder.append(this.serverURLPrefix);
|
||||
builder.append(", isDistributed=");
|
||||
|
|
|
@ -31,6 +31,7 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
|||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentialService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentials;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
|
@ -50,6 +51,7 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
private final ClientCredentialService clientCredentialService;
|
||||
private final ClientHttpRequestFactory clientHttpRequestFactory;
|
||||
private final String[] openEdxAlternativeTokenRequestPaths;
|
||||
private final WebserviceInfo webserviceInfo;
|
||||
|
||||
private final Map<CacheKey, LmsAPITemplate> cache = new ConcurrentHashMap<>();
|
||||
|
||||
|
@ -58,12 +60,14 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
final LmsSetupDAO lmsSetupDAO,
|
||||
final ClientCredentialService clientCredentialService,
|
||||
final ClientHttpRequestFactory clientHttpRequestFactory,
|
||||
final WebserviceInfo webserviceInfo,
|
||||
@Value("${sebserver.webservice.lms.openedx.api.token.request.paths}") final String alternativeTokenRequestPaths) {
|
||||
|
||||
this.asyncService = asyncService;
|
||||
this.lmsSetupDAO = lmsSetupDAO;
|
||||
this.clientCredentialService = clientCredentialService;
|
||||
this.clientHttpRequestFactory = clientHttpRequestFactory;
|
||||
this.webserviceInfo = webserviceInfo;
|
||||
|
||||
this.openEdxAlternativeTokenRequestPaths = (alternativeTokenRequestPaths != null)
|
||||
? StringUtils.split(alternativeTokenRequestPaths, Constants.LIST_SEPARATOR)
|
||||
|
@ -203,7 +207,8 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
credentials,
|
||||
this.clientCredentialService,
|
||||
this.clientHttpRequestFactory,
|
||||
this.openEdxAlternativeTokenRequestPaths);
|
||||
this.openEdxAlternativeTokenRequestPaths,
|
||||
this.webserviceInfo);
|
||||
default:
|
||||
throw new UnsupportedOperationException("No support for LMS Type: " + lmsSetup.lmsType);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -54,6 +55,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
|||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentialService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentials;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
|
@ -76,6 +78,7 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
|||
private final ClientHttpRequestFactory clientHttpRequestFactory;
|
||||
private final ClientCredentialService clientCredentialService;
|
||||
private final Set<String> knownTokenAccessPaths;
|
||||
private final WebserviceInfo webserviceInfo;
|
||||
|
||||
private OAuth2RestTemplate restTemplate = null;
|
||||
private final MemoizingCircuitBreaker<List<QuizData>> allQuizzesSupplier;
|
||||
|
@ -86,12 +89,14 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
|||
final ClientCredentials credentials,
|
||||
final ClientCredentialService clientCredentialService,
|
||||
final ClientHttpRequestFactory clientHttpRequestFactory,
|
||||
final String[] alternativeTokenRequestPaths) {
|
||||
final String[] alternativeTokenRequestPaths,
|
||||
final WebserviceInfo webserviceInfo) {
|
||||
|
||||
this.lmsSetup = lmsSetup;
|
||||
this.clientCredentialService = clientCredentialService;
|
||||
this.credentials = credentials;
|
||||
this.clientHttpRequestFactory = clientHttpRequestFactory;
|
||||
this.webserviceInfo = webserviceInfo;
|
||||
this.knownTokenAccessPaths = new HashSet<>();
|
||||
this.knownTokenAccessPaths.add(OPEN_EDX_DEFAULT_TOKEN_REQUEST_PATH);
|
||||
if (alternativeTokenRequestPaths != null) {
|
||||
|
@ -234,12 +239,13 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
|||
}
|
||||
|
||||
private ArrayList<QuizData> collectAllQuizzes(final LmsSetup lmsSetup) {
|
||||
final String externalStartURI = getExternalLMSServerAddress(lmsSetup);
|
||||
return collectAllCourses(lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_ENDPOINT)
|
||||
.stream()
|
||||
.reduce(
|
||||
new ArrayList<QuizData>(),
|
||||
(list, courseData) -> {
|
||||
list.add(quizDataOf(lmsSetup, courseData));
|
||||
list.add(quizDataOf(lmsSetup, courseData, externalStartURI));
|
||||
return list;
|
||||
},
|
||||
(list1, list2) -> {
|
||||
|
@ -248,6 +254,28 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
|||
});
|
||||
}
|
||||
|
||||
private String getExternalLMSServerAddress(final LmsSetup lmsSetup) {
|
||||
final String externalAddressAlias = this.webserviceInfo.getExternalAddressAlias(lmsSetup.lmsApiUrl);
|
||||
String _externalStartURI = lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_START_URL_PREFIX;
|
||||
if (StringUtils.isNoneBlank(externalAddressAlias)) {
|
||||
try {
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Found external address alias: {}", externalAddressAlias);
|
||||
}
|
||||
|
||||
final URL url = new URL(lmsSetup.lmsApiUrl);
|
||||
final int port = url.getPort();
|
||||
_externalStartURI = this.webserviceInfo.getHttpScheme() + "://" + externalAddressAlias + ":" + port;
|
||||
|
||||
log.info("Use external address for course access: {}", _externalStartURI);
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to create external address from alias: ", e);
|
||||
}
|
||||
}
|
||||
return _externalStartURI;
|
||||
}
|
||||
|
||||
private List<CourseData> collectAllCourses(final String pageURI) {
|
||||
final List<CourseData> collector = new ArrayList<>();
|
||||
EdXPage page = getEdxPage(pageURI).getBody();
|
||||
|
@ -275,9 +303,10 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
|||
|
||||
private static QuizData quizDataOf(
|
||||
final LmsSetup lmsSetup,
|
||||
final CourseData courseData) {
|
||||
final CourseData courseData,
|
||||
final String uriPrefix) {
|
||||
|
||||
final String startURI = lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_START_URL_PREFIX + courseData.id;
|
||||
final String startURI = uriPrefix + courseData.id;
|
||||
final Map<String, String> additionalAttrs = new HashMap<>();
|
||||
additionalAttrs.put("blocks_url", courseData.blocks_url);
|
||||
return new QuizData(
|
||||
|
|
|
@ -38,6 +38,7 @@ sebserver.webservice.api.exam.accessTokenValiditySeconds=86400
|
|||
sebserver.webservice.api.pagination.maxPageSize=500
|
||||
# comma separated list of known possible OpenEdX API access token request endpoints
|
||||
sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token
|
||||
sebserver.webservice.lms.address.alias=lms.mockup.com=ralph.ethz.ch,edx.devstack.lms=ralph.ethz.ch
|
||||
# write logs to
|
||||
logging.file=log/sebserver.log
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue