Skip to content
Snippets Groups Projects
Commit f926106a authored by uhensler's avatar uhensler
Browse files

OO-5128: Deletion of Opencast events from presentation service

parent f3b88190
No related branches found
No related tags found
No related merge requests found
Showing
with 203 additions and 6 deletions
...@@ -46,6 +46,7 @@ public class OpencastModule extends AbstractSpringModule implements ConfigOnOff ...@@ -46,6 +46,7 @@ public class OpencastModule extends AbstractSpringModule implements ConfigOnOff
private static final String ENABLED = "opencast.enabled"; private static final String ENABLED = "opencast.enabled";
private static final String API_URL = "api.url"; private static final String API_URL = "api.url";
private static final String API_PRESENTATION_URL = "api.presentation.url";
private static final String API_USERNAME = "api.username"; private static final String API_USERNAME = "api.username";
private static final String API_PASSOWRD = "api.password"; private static final String API_PASSOWRD = "api.password";
private static final String LTI_URL = "lti.url"; private static final String LTI_URL = "lti.url";
...@@ -64,6 +65,8 @@ public class OpencastModule extends AbstractSpringModule implements ConfigOnOff ...@@ -64,6 +65,8 @@ public class OpencastModule extends AbstractSpringModule implements ConfigOnOff
private boolean enabled; private boolean enabled;
@Value("${opencast.api.url}") @Value("${opencast.api.url}")
private String apiUrl; private String apiUrl;
@Value("${opencast.api.presentation.url}")
private String apiPresentationUrl;
@Value("${opencast.api.username}") @Value("${opencast.api.username}")
private String apiUsername; private String apiUsername;
@Value("${opencast.api.password}") @Value("${opencast.api.password}")
...@@ -106,6 +109,7 @@ public class OpencastModule extends AbstractSpringModule implements ConfigOnOff ...@@ -106,6 +109,7 @@ public class OpencastModule extends AbstractSpringModule implements ConfigOnOff
} }
apiUrl = getStringPropertyValue(API_URL, apiUrl); apiUrl = getStringPropertyValue(API_URL, apiUrl);
apiPresentationUrl = getStringPropertyValue(API_PRESENTATION_URL, apiPresentationUrl);
apiUsername = getStringPropertyValue(API_USERNAME, apiUsername); apiUsername = getStringPropertyValue(API_USERNAME, apiUsername);
apiPassword = getStringPropertyValue(API_PASSOWRD, apiPassword); apiPassword = getStringPropertyValue(API_PASSOWRD, apiPassword);
refreshApiAuthorization(); refreshApiAuthorization();
...@@ -158,6 +162,15 @@ public class OpencastModule extends AbstractSpringModule implements ConfigOnOff ...@@ -158,6 +162,15 @@ public class OpencastModule extends AbstractSpringModule implements ConfigOnOff
setStringProperty(API_URL, apiUrl, true); setStringProperty(API_URL, apiUrl, true);
} }
public String getApiPresentationUrl() {
return apiPresentationUrl;
}
public void setApiPresentationUrl(String apiPresentationUrl) {
this.apiPresentationUrl = apiPresentationUrl;
setStringProperty(API_PRESENTATION_URL, apiPresentationUrl, true);
}
public String getApiUrl() { public String getApiUrl() {
return apiUrl; return apiUrl;
} }
......
...@@ -142,6 +142,19 @@ public class OpencastRestClient { ...@@ -142,6 +142,19 @@ public class OpencastRestClient {
} }
public boolean deleteEvent(String identifier) { public boolean deleteEvent(String identifier) {
boolean deleted = true;
Event event = getEvent(identifier);
if (event != null) {
deleted &= deleteEventFromAdmin(identifier);
}
if (isEpisodeExisting(identifier)) {
deleted &= deleteEpisode(identifier);
}
return deleted;
}
private boolean deleteEventFromAdmin(String identifier) {
URI uri = URI.create(opencastModule.getApiUrl() + "/events/" + identifier); URI uri = URI.create(opencastModule.getApiUrl() + "/events/" + identifier);
HttpDelete request = new HttpDelete(uri); HttpDelete request = new HttpDelete(uri);
decorateRequest(request); decorateRequest(request);
...@@ -213,6 +226,53 @@ public class OpencastRestClient { ...@@ -213,6 +226,53 @@ public class OpencastRestClient {
return NO_SERIES; return NO_SERIES;
} }
public boolean isEpisodeExisting(String identifier) {
URI uri;
try {
uri = new URIBuilder(opencastModule.getApiPresentationUrl() + "/episode.json")
.addParameter("id", identifier)
.build();
} catch (Exception e) {
log.error("Cannot get Opencast episode.", e);
return false;
}
HttpGet request = new HttpGet(uri);
decorateRequest(request);
try(CloseableHttpClient client = HttpClientBuilder.create().build();
CloseableHttpResponse response = client.execute(request)) {
int statusCode = response.getStatusLine().getStatusCode();
log.debug("Status code of: {} {}", uri, statusCode);
if (statusCode == HttpStatus.SC_OK) {
String json = EntityUtils.toString(response.getEntity(), "UTF-8");
SearchResult result = objectMapper.readValue(json, SearchResult.class);
return result.getSearchResults().getTotal() > 0;
}
} catch(Exception e) {
log.error("Cannot send: {}", uri, e);
}
return false;
}
private boolean deleteEpisode(String identifier) {
URI uri = URI.create(opencastModule.getApiPresentationUrl() + "/" + identifier);
HttpDelete request = new HttpDelete(uri);
decorateRequest(request);
try(CloseableHttpClient client = HttpClientBuilder.create().build();
CloseableHttpResponse response = client.execute(request)) {
int statusCode = response.getStatusLine().getStatusCode();
log.debug("Status code of: {} {}", uri, statusCode);
if (statusCode == HttpStatus.SC_NO_CONTENT || statusCode == HttpStatus.SC_OK) {
return true;
}
} catch(Exception e) {
log.error("Cannot send: {}", uri, e);
}
return false;
}
private void decorateRequest(HttpGet request, AuthDelegate authDelegate) { private void decorateRequest(HttpGet request, AuthDelegate authDelegate) {
decorateRequest(request); decorateRequest(request);
if (AuthDelegate.Type.User == authDelegate.getType()) { if (AuthDelegate.Type.User == authDelegate.getType()) {
......
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.opencast.manager.client;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* Initial date: 4 Dec 2020<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
@JsonIgnoreProperties(ignoreUnknown=true)
public class SearchResult {
@JsonProperty("search-results")
private SearchResults searchResults;
public SearchResults getSearchResults() {
return searchResults;
}
public void setSearchResults(SearchResults searchResults) {
this.searchResults = searchResults;
}
}
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.opencast.manager.client;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
*
* Initial date: 4 Dec 2020<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
@JsonIgnoreProperties(ignoreUnknown=true)
public class SearchResults {
private int total;
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
}
...@@ -59,6 +59,7 @@ public class OpencastAdminController extends FormBasicController { ...@@ -59,6 +59,7 @@ public class OpencastAdminController extends FormBasicController {
private MultipleSelectionElement enabledEl; private MultipleSelectionElement enabledEl;
private TextElement apiUrlEl; private TextElement apiUrlEl;
private TextElement apiUrlPresentationEl;
private TextElement apiUsernameEl; private TextElement apiUsernameEl;
private TextElement apiPasswordEl; private TextElement apiPasswordEl;
private TextElement ltiUrlEl; private TextElement ltiUrlEl;
...@@ -103,6 +104,11 @@ public class OpencastAdminController extends FormBasicController { ...@@ -103,6 +104,11 @@ public class OpencastAdminController extends FormBasicController {
apiUrlEl.setExampleKey("admin.api.url.example", null); apiUrlEl.setExampleKey("admin.api.url.example", null);
apiUrlEl.setMandatory(true); apiUrlEl.setMandatory(true);
String apiPresentationUrl = opencastModule.getApiPresentationUrl();
apiUrlPresentationEl = uifactory.addTextElement("admin.api.presentation.url", "admin.api.presentation.url", 128, apiPresentationUrl, formLayout);
apiUrlPresentationEl.setExampleKey("admin.api.presentation.url.example", null);
apiUrlPresentationEl.setMandatory(true);
String apiUsername = opencastModule.getApiUsername(); String apiUsername = opencastModule.getApiUsername();
apiUsernameEl = uifactory.addTextElement("admin.api.username", 128, apiUsername, formLayout); apiUsernameEl = uifactory.addTextElement("admin.api.username", 128, apiUsername, formLayout);
apiUsernameEl.setMandatory(true); apiUsernameEl.setMandatory(true);
...@@ -218,6 +224,7 @@ public class OpencastAdminController extends FormBasicController { ...@@ -218,6 +224,7 @@ public class OpencastAdminController extends FormBasicController {
//validate only if the module is enabled //validate only if the module is enabled
if(enabledEl.isAtLeastSelected(1)) { if(enabledEl.isAtLeastSelected(1)) {
allOk &= validateIsMandatory(apiUrlEl); allOk &= validateIsMandatory(apiUrlEl);
allOk &= validateIsMandatory(apiUrlPresentationEl);
allOk &= validateIsMandatory(apiUsernameEl); allOk &= validateIsMandatory(apiUsernameEl);
allOk &= validateIsMandatory(apiPasswordEl); allOk &= validateIsMandatory(apiPasswordEl);
allOk &= validateIsMandatory(ltiUrlEl); allOk &= validateIsMandatory(ltiUrlEl);
...@@ -251,6 +258,10 @@ public class OpencastAdminController extends FormBasicController { ...@@ -251,6 +258,10 @@ public class OpencastAdminController extends FormBasicController {
apiUrl = apiUrl.endsWith("/")? apiUrl.substring(0, apiUrl.length() - 1): apiUrl; apiUrl = apiUrl.endsWith("/")? apiUrl.substring(0, apiUrl.length() - 1): apiUrl;
opencastModule.setApiUrl(apiUrl); opencastModule.setApiUrl(apiUrl);
String apiPresentationUrl = apiUrlPresentationEl.getValue();
apiPresentationUrl = apiPresentationUrl.endsWith("/")? apiPresentationUrl.substring(0, apiPresentationUrl.length() - 1): apiPresentationUrl;
opencastModule.setApiPresentationUrl(apiPresentationUrl);
String apiUsername = apiUsernameEl.getValue(); String apiUsername = apiUsernameEl.getValue();
String apiPassword = apiPasswordEl.getValue(); String apiPassword = apiPasswordEl.getValue();
opencastModule.setApiCredentials(apiUsername, apiPassword); opencastModule.setApiCredentials(apiUsername, apiPassword);
......
admin.api.password=API Passwort admin.api.password=API Passwort
admin.api.url=API URL admin.api.presentation.url=API URL (presentation)
admin.api.presentation.url.example=https://presentation.opencast.example.com/search
admin.api.url=API URL (admin)
admin.api.url.example=https://admin.opencast.example.com/api admin.api.url.example=https://admin.opencast.example.com/api
admin.api.username=API Benutzername admin.api.username=API Benutzername
admin.auth.delegate.roles=Autorisierungsrollen admin.auth.delegate.roles=Autorisierungsrollen
......
admin.api.password=API Password admin.api.password=API Password
admin.api.url=API URL admin.api.presentation.url=API URL (presentation)
admin.api.presentation.url.example=https://presentation.opencast.example.com/search
admin.api.url=API URL (admin)
admin.api.url.example=https://admin.opencast.example.com/api admin.api.url.example=https://admin.opencast.example.com/api
admin.api.username=API Username admin.api.username=API Username
admin.auth.delegate.roles=Authorization roles admin.auth.delegate.roles=Authorization roles
......
#Fri Aug 14 07:01:32 CEST 2020 #Fri Aug 14 07:01:32 CEST 2020
admin.api.password=Mot de passe API admin.api.password=Mot de passe API
admin.api.url=URL de l'API (LTI)
admin.api.url.example=https\://admin.opencast.example.com/api admin.api.url.example=https\://admin.opencast.example.com/api
admin.api.username=Nom d'utilisateur de l'API admin.api.username=Nom d'utilisateur de l'API
admin.auth.delegate.roles=R\u00F4les des autorisations admin.auth.delegate.roles=R\u00F4les des autorisations
......
#Sun Aug 30 15:40:09 CEST 2020 #Sun Aug 30 15:40:09 CEST 2020
admin.api.password=API Password admin.api.password=API Password
admin.api.url=API URL
admin.api.url.example=https\://admin.opencast.example.com/api admin.api.url.example=https\://admin.opencast.example.com/api
admin.api.username=Nome utente API admin.api.username=Nome utente API
admin.auth.delegate.roles=Ruoli delle autorizzazioni admin.auth.delegate.roles=Ruoli delle autorizzazioni
......
#Fri Sep 25 19:49:48 CEST 2020 #Fri Sep 25 19:49:48 CEST 2020
admin.api.password=Senha API admin.api.password=Senha API
admin.api.url=URL API
admin.api.url.example=https\://admin.opencast.example.com/api admin.api.url.example=https\://admin.opencast.example.com/api
admin.api.username=Usu\u00E1rio da API admin.api.username=Usu\u00E1rio da API
admin.auth.delegate.roles=Fun\u00E7\u00F5es de autoriza\u00E7\u00E3o admin.auth.delegate.roles=Fun\u00E7\u00F5es de autoriza\u00E7\u00E3o
......
...@@ -1780,7 +1780,10 @@ youtube.api.key= ...@@ -1780,7 +1780,10 @@ youtube.api.key=
############################################################################### ###############################################################################
opencast.enabled=false opencast.enabled=false
# API # API
# REST endpoint of the admin service
opencast.api.url=https://admin.opencast.example.com/api opencast.api.url=https://admin.opencast.example.com/api
# REST endpoint of the presentation service
opencast.api.presentation.url=https://presentation.opencast.example.com/search
# Username and password of the technical opencast user # Username and password of the technical opencast user
opencast.api.username= opencast.api.username=
opencast.api.password= opencast.api.password=
......
...@@ -48,7 +48,8 @@ public class OpencastRestClientTest extends OlatTestCase { ...@@ -48,7 +48,8 @@ public class OpencastRestClientTest extends OlatTestCase {
@Before @Before
public void setUp() { public void setUp() {
opencastModule.setApiUrl("http://localhost:8480"); opencastModule.setApiUrl("http://localhost:8480/api");
opencastModule.setApiPresentationUrl("http://localhost:8480/search");
opencastModule.setApiCredentials("admin", "opencast"); opencastModule.setApiCredentials("admin", "opencast");
} }
...@@ -99,4 +100,24 @@ public class OpencastRestClientTest extends OlatTestCase { ...@@ -99,4 +100,24 @@ public class OpencastRestClientTest extends OlatTestCase {
softly.assertAll(); softly.assertAll();
} }
@Test
public void shouldDeleteEvent() throws InterruptedException {
String identifier = "41a88d0d-a9f4-4928-81cf-7a23fef2f992";
SoftAssertions softly = new SoftAssertions();
softly.assertThat(sut.getEvent(identifier)).as("Event exists in admin").isNotNull();
softly.assertThat(sut.isEpisodeExisting(identifier)).as("Episode exists in presentation").isTrue();
softly.assertThat(sut.deleteEvent(identifier)).as("deleted").isTrue();
Thread.sleep(5000);
softly.assertThat(sut.getEvent(identifier)).as("Event does not exist in admin anymore").isNull();
softly.assertThat(sut.isEpisodeExisting(identifier)).as("Episode does not exist in presentation anymore").isFalse();
softly.assertThat(sut.deleteEvent(identifier)).as("2. deleted").isTrue(); // because nothing to delete
softly.assertAll();
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment