introduces external server address alias config-property

This commit is contained in:
anhefti 2019-09-09 09:33:55 +02:00
parent 70c1c09432
commit 9b105ab476
4 changed files with 85 additions and 6 deletions

View file

@ -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=");

View file

@ -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);
}

View file

@ -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(

View file

@ -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