org.opencastproject.kernel.bundleinfo.BundleInfoRestEndpoint Maven / Gradle / Ivy
/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License
* at:
*
* http://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.opencastproject.kernel.bundleinfo;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.TEXT_PLAIN_TYPE;
import static org.opencastproject.util.EqualsUtil.ne;
import static org.opencastproject.util.Jsons.arr;
import static org.opencastproject.util.Jsons.obj;
import static org.opencastproject.util.Jsons.p;
import static org.opencastproject.util.Jsons.stringVal;
import static org.opencastproject.util.RestUtil.R.notFound;
import static org.opencastproject.util.RestUtil.R.ok;
import static org.opencastproject.util.data.Collections.set;
import static org.opencastproject.util.data.Collections.toArray;
import static org.opencastproject.util.data.Monadics.mlist;
import org.opencastproject.util.Jsons;
import org.opencastproject.util.data.Function;
import org.opencastproject.util.data.Monadics;
import org.opencastproject.util.data.Option;
import org.opencastproject.util.data.functions.Functions;
import org.opencastproject.util.doc.rest.RestParameter;
import org.opencastproject.util.doc.rest.RestQuery;
import org.opencastproject.util.doc.rest.RestResponse;
import org.opencastproject.util.doc.rest.RestService;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
/** Bundle information via REST. */
@RestService(
name = "systemInfo",
title = "System Bundle Info",
notes = { "This is used to display the version information on the login page." },
abstractText = "The system bundle info endpoint yields information about the running OSGi bundles of Opencast.")
public abstract class BundleInfoRestEndpoint {
private static final String DEFAULT_BUNDLE_PREFIX = "opencast";
protected abstract BundleInfoDb getDb();
@GET
// path prefix "bundles" is contained here and not in the path annotation of the class
// See https://opencast.jira.com/browse/MH-9768
@Path("bundles/list")
@Produces(APPLICATION_JSON)
@RestQuery(
name = "list",
description = "Return a list of all running bundles on the whole cluster.",
reponses = {
@RestResponse(description = "A list of bundles.", responseCode = HttpServletResponse.SC_OK) },
returnDescription = "The search results, expressed as xml or json.")
public Response getVersions() {
final Monadics.ListMonadic bundleInfos = mlist(getDb().getBundles()).map(
Functions. co(bundleInfo));
return ok(obj(p("bundleInfos", arr(bundleInfos)), p("count", bundleInfos.value().size())));
}
/** Return true if all bundles have the same bundle version and build number. */
@GET
@Path("bundles/check")
@RestQuery(
name = "check",
description = "Check if all bundles throughout the cluster have the same OSGi bundle version and build number.",
restParameters = {
@RestParameter(
name = "prefix",
description = "The bundle name prefixes to check. Defaults to '" + DEFAULT_BUNDLE_PREFIX + "'.",
isRequired = false,
defaultValue = DEFAULT_BUNDLE_PREFIX,
type = RestParameter.Type.STRING) },
reponses = {
@RestResponse(description = "true/false", responseCode = HttpServletResponse.SC_OK),
@RestResponse(description = "cannot find any bundles with the given prefix", responseCode = HttpServletResponse.SC_NOT_FOUND) },
returnDescription = "The search results, expressed as xml or json.")
public Response checkBundles(@DefaultValue(DEFAULT_BUNDLE_PREFIX) @QueryParam("prefix") List prefixes) {
return withBundles(prefixes, new Function, Response>() {
@Override
public Response apply(List infos) {
final String bundleVersion = infos.get(0).getBundleVersion();
final Option buildNumber = infos.get(0).getBuildNumber();
for (BundleInfo a : infos) {
if (ne(a.getBundleVersion(), bundleVersion) || ne(a.getBuildNumber(), buildNumber))
return ok(TEXT_PLAIN_TYPE, "false");
}
return ok(TEXT_PLAIN_TYPE, "true");
}
});
}
/** Return the common version of all bundles matching the given prefix. */
@GET
@Path("bundles/version")
@Produces(APPLICATION_JSON)
@RestQuery(
name = "bundleVersion",
description = "Return the common OSGi build version and build number of all bundles matching the given prefix.",
restParameters = {
@RestParameter(
name = "prefix",
description = "The bundle name prefixes to check. Defaults to '" + DEFAULT_BUNDLE_PREFIX + "'.",
isRequired = false,
defaultValue = DEFAULT_BUNDLE_PREFIX,
type = RestParameter.Type.STRING) },
reponses = {
@RestResponse(description = "Version structure", responseCode = HttpServletResponse.SC_OK),
@RestResponse(description = "No bundles with the given prefix", responseCode = HttpServletResponse.SC_NOT_FOUND) },
returnDescription = "The search results as json.")
public Response getBundleVersion(@DefaultValue(DEFAULT_BUNDLE_PREFIX) @QueryParam("prefix") List prefixes) {
return withBundles(prefixes, new Function, Response>() {
@Override
public Response apply(List infos) {
final Set versions = set();
for (BundleInfo bundle : infos) {
versions.add(bundle.getVersion());
}
final BundleInfo example = infos.get(0);
switch (versions.size()) {
case 0:
// no versions...
throw new Error("bug");
case 1:
// all versions align
return ok(obj(p("consistent", true)).append(fullVersionJson.apply(example.getVersion())));
default:
// multiple versions found
return ok(obj(p("consistent", false),
p("versions",
arr(mlist(versions.iterator())
.map(Functions. co(fullVersionJson))))));
}
}
});
}
public static final Function fullVersionJson = new Function() {
@Override
public Jsons.Obj apply(BundleVersion version) {
return obj(p("version", version.getBundleVersion()), p("buildNumber", version.getBuildNumber().map(stringVal)));
}
};
public static Jsons.Obj bundleInfoJson(BundleInfo bundle) {
return obj(p("host", bundle.getHost()), p("bundleSymbolicName", bundle.getBundleSymbolicName()),
p("bundleId", bundle.getBundleId())).append(fullVersionJson.apply(bundle.getVersion()));
}
public static final Function bundleInfo = new Function() {
@Override
public Jsons.Obj apply(BundleInfo bundle) {
return bundleInfoJson(bundle);
}
};
/** Run f
if there is at least one bundle matching the given prefixes. */
private Response withBundles(List prefixes, Function, Response> f) {
final List info = getDb().getBundles(toArray(String.class, prefixes));
if (info.size() > 0) {
return f.apply(info);
} else {
return notFound("No bundles match one of the given prefixes");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy