use of org.opensolaris.opengrok.configuration.Project in project OpenGrok by OpenGrok.
the class ProjectMessage method applyMessage.
@Override
protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {
String command = getText();
validateMore(env);
switch(command) {
case "add":
for (String projectName : getTags()) {
File srcRoot = env.getSourceRootFile();
File projDir = new File(srcRoot, projectName);
if (!env.getProjects().containsKey(projectName)) {
Project project = new Project(projectName, "/" + projectName);
project.setTabSize(env.getConfiguration().getTabSize());
// Add repositories in this project.
List<RepositoryInfo> repos = getRepositoriesInDir(env, projDir);
env.addRepositories(repos);
env.getProjectRepositoriesMap().put(project, repos);
// Finally introduce the project to the configuration.
// Note that the project is inactive in the UI until it is indexed.
// See {@code isIndexed()}
env.getProjects().put(projectName, project);
Set<Project> projectSet = new TreeSet<>();
projectSet.add(project);
env.populateGroups(env.getGroups(), projectSet);
} else {
Project project = env.getProjects().get(projectName);
Map<Project, List<RepositoryInfo>> map = env.getProjectRepositoriesMap();
// Refresh the list of repositories of this project.
// This is the goal of this action: if an existing project
// is re-added, this means its list of repositories has changed.
List<RepositoryInfo> repos = getRepositoriesInDir(env, projDir);
List<RepositoryInfo> allrepos = env.getRepositories();
synchronized (allrepos) {
// newly added repository
for (RepositoryInfo repo : repos) {
if (!allrepos.contains(repo)) {
allrepos.add(repo);
}
}
// deleted repository
for (RepositoryInfo repo : map.get(project)) {
if (!repos.contains(repo)) {
allrepos.remove(repo);
}
}
}
map.put(project, repos);
}
}
break;
case "delete":
for (String projectName : getTags()) {
Project proj = env.getProjects().get(projectName);
if (proj == null) {
throw new Exception("cannot get project \"" + projectName + "\"");
}
LOGGER.log(Level.INFO, "deleting configuration for project " + projectName);
// Remove the project from its groups.
for (Group group : proj.getGroups()) {
group.getRepositories().remove(proj);
group.getProjects().remove(proj);
}
// Now remove the repositories associated with this project.
List<RepositoryInfo> repos = env.getProjectRepositoriesMap().get(proj);
env.getRepositories().removeAll(repos);
env.getProjectRepositoriesMap().remove(proj);
env.getProjects().remove(projectName, proj);
// Prevent the project to be included in new searches.
env.refreshSearcherManagerMap();
// Lastly, remove data associated with the project.
LOGGER.log(Level.INFO, "deleting data for project " + projectName);
for (String dirName : new String[] { IndexDatabase.INDEX_DIR, IndexDatabase.XREF_DIR }) {
IOUtils.removeRecursive(Paths.get(env.getDataRootPath() + File.separator + dirName + File.separator + projectName));
}
HistoryGuru guru = HistoryGuru.getInstance();
guru.removeCache(repos.stream().map((x) -> {
try {
return env.getPathRelativeToSourceRoot(new File((x).getDirectoryName()));
} catch (ForbiddenSymlinkException e) {
LOGGER.log(Level.FINER, e.getMessage());
return "";
} catch (IOException e) {
LOGGER.log(Level.INFO, "cannot remove files for repository {0}", x.getDirectoryName());
// {@code removeCache()} will return nothing.
return "";
}
}).collect(Collectors.toSet()));
}
break;
case "indexed":
for (String projectName : getTags()) {
Project project;
if ((project = env.getProjects().get(projectName)) != null) {
project.setIndexed(true);
// Refresh current version of the project's repositories.
List<RepositoryInfo> riList = env.getProjectRepositoriesMap().get(project);
if (riList != null) {
for (RepositoryInfo ri : riList) {
Repository repo = getRepository(ri);
if (repo != null && repo.getCurrentVersion() != null && repo.getCurrentVersion().length() > 0) {
// getRepository() always creates fresh instance
// of the Repository object so there is no need
// to call setCurrentVersion() on it.
ri.setCurrentVersion(repo.determineCurrentVersion());
}
}
}
} else {
LOGGER.log(Level.WARNING, "cannot find project " + projectName + " to mark as indexed");
}
}
// In case this project has just been incrementally indexed,
// its IndexSearcher needs a poke.
env.maybeRefreshIndexSearchers(getTags());
env.refreshDateForLastIndexRun();
break;
case "list":
return (env.getProjectNames().stream().collect(Collectors.joining("\n")).getBytes());
case "list-indexed":
return (env.getProjectList().stream().filter(p -> p.isIndexed()).map(p -> p.getName()).collect(Collectors.joining("\n")).getBytes());
case "get-repos":
List<String> repos = new ArrayList<>();
for (String projectName : getTags()) {
Project project;
if ((project = env.getProjects().get(projectName)) == null) {
continue;
}
List<RepositoryInfo> infos = env.getProjectRepositoriesMap().get(project);
if (infos != null) {
repos.addAll(infos.stream().map(ri -> ri.getDirectoryNameRelative()).collect(Collectors.toList()));
}
}
return repos.stream().collect(Collectors.joining("\n")).getBytes();
case "get-repos-type":
Set<String> types = new TreeSet<>();
for (String projectName : getTags()) {
Project project;
if ((project = env.getProjects().get(projectName)) == null) {
continue;
}
List<RepositoryInfo> infos = env.getProjectRepositoriesMap().get(project);
if (infos != null) {
types.addAll(infos.stream().map(ri -> ri.getType()).collect(Collectors.toList()));
}
}
return types.stream().collect(Collectors.joining("\n")).getBytes();
}
return ("command \"" + getText() + "\" for projects " + String.join(",", getTags()) + " done").getBytes();
}
use of org.opensolaris.opengrok.configuration.Project in project OpenGrok by OpenGrok.
the class AuthorizationEntityTest method testForGroupsAndForProjectsDiscoveryInvalidProjectInGroup.
/**
* Listed projects in the group don't exist.
*/
@Test
public void testForGroupsAndForProjectsDiscoveryInvalidProjectInGroup() {
AuthorizationEntity authEntity = authEntityFactory.apply(null);
authEntity.setForGroups(new TreeSet<>(Arrays.asList(new String[] { "group 1", "group 2" })));
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
Group g1 = new Group();
g1.setName("group 1");
g1.addProject(new Project("project 1"));
g1.addProject(new Project("project 2"));
g1.addProject(new Project("project 3"));
env.getGroups().add(g1);
authEntity.load(new TreeMap<>());
assertEquals(new TreeSet<>(Arrays.asList(new String[] { "group 1" })), authEntity.forGroups());
assertEquals(new TreeSet<>(), authEntity.forProjects());
}
use of org.opensolaris.opengrok.configuration.Project in project OpenGrok by OpenGrok.
the class AuthorizationFrameworkReloadTest method testReloadCycle.
/**
* Sort of a stress test - call isAllowed() and reload() in parallel.
* This might uncover any snags with locking within AuthorizationFramework.
*/
@Test
public void testReloadCycle() {
Statistics stats = RuntimeEnvironment.getInstance().getStatistics();
Long reloads;
String projectName = "project" + Math.random();
// Create authorization stack for single project.
AuthorizationStack stack = new AuthorizationStack(AuthControlFlag.REQUIRED, "stack for project " + projectName);
assertNotNull(stack);
stack.add(new AuthorizationPlugin(AuthControlFlag.REQUIRED, "opengrok.auth.plugin.FalsePlugin"));
stack.setForProjects(projectName);
AuthorizationFramework framework = new AuthorizationFramework(pluginDirectory.getPath(), stack);
// to avoid noise when loading classes of other tests
framework.setLoadClasses(false);
framework.reload();
// Perform simple sanity check before long run is entered. If this fails,
// it will be waste of time to continue with the test.
Project p = new Project(projectName);
DummyHttpServletRequest req = new DummyHttpServletRequest();
assertFalse(framework.isAllowed(req, p));
// Create a thread that does reload() every now and then.
runThread = true;
final int maxReloadSleep = 10;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (runThread) {
framework.reload();
try {
Thread.sleep((long) (Math.random() % maxReloadSleep) + 1);
} catch (InterruptedException ex) {
}
}
}
});
t.start();
reloads = stats.getRequest("authorization_stack_reload");
assertNotNull(reloads);
// Process number or requests and check that framework decision is consistent.
for (int i = 0; i < 1000; i++) {
req = new DummyHttpServletRequest();
assertFalse(framework.isAllowed(req, p));
try {
// Should run more frequently than the thread performing reload().
Thread.sleep((long) (Math.random() % (maxReloadSleep / 3)) + 1);
} catch (InterruptedException ex) {
}
}
try {
// Terminate the thread.
runThread = false;
t.join();
} catch (InterruptedException ex) {
}
// Double check that at least one reload() was done.
reloads = stats.getRequest("authorization_stack_reload") - reloads;
System.out.println("number of reloads: " + reloads);
assertTrue(reloads > 0);
}
use of org.opensolaris.opengrok.configuration.Project in project OpenGrok by OpenGrok.
the class UserPluginTest method testTimeoutedUser.
@Test
public void testTimeoutedUser() {
HttpServletRequest req;
Assert.assertFalse(plugin.isAllowed(req = createRequest("007", true), new Group()));
Assert.assertNull(req.getAttribute(UserPlugin.REQUEST_ATTR));
Assert.assertFalse(plugin.isAllowed(req = createRequest("008", true), new Project()));
Assert.assertNull(req.getAttribute(UserPlugin.REQUEST_ATTR));
Assert.assertFalse(plugin.isAllowed(req = createRequest("009", true), createGroup("some group")));
Assert.assertNull(req.getAttribute(UserPlugin.REQUEST_ATTR));
Assert.assertFalse(plugin.isAllowed(req = createRequest("00A", true), createProject("some project")));
Assert.assertNull(req.getAttribute(UserPlugin.REQUEST_ATTR));
}
use of org.opensolaris.opengrok.configuration.Project in project OpenGrok by OpenGrok.
the class Indexer method parseOptions.
/**
* Parse OpenGrok Indexer options
* This method was created so that it would be easier to write unit
* tests against the Indexer option parsing mechanism.
*
* @param argv the command line arguments
* @return array of remaining non option arguments
* @throws ParseException if parsing failed
*/
public static String[] parseOptions(String[] argv) throws ParseException {
String[] usage = { "--help" };
String program = "opengrok.jar";
final String[] ON_OFF = { ON, OFF };
final String[] REMOTE_REPO_CHOICES = { ON, OFF, DIRBASED, UIONLY };
final String[] LUCENE_LOCKS = { ON, OFF, "simple", "native" };
if (argv.length == 0) {
// will force usage output
argv = usage;
status = 1;
}
OptionParser configure = OptionParser.scan(parser -> {
parser.on("-R configPath").Do(cfgFile -> {
try {
cfg = Configuration.read(new File((String) cfgFile));
} catch (IOException e) {
die(e.getMessage());
}
});
});
// An example of how to add a data type for option parsing
OptionParser.accept(WebAddress.class, s -> {
return parseWebAddress(s);
});
openGrok = OptionParser.Do(parser -> {
parser.setPrologue(String.format("\nUsage: java -jar %s [options] [subDir1 [...]]\n", program));
parser.on("-?", "-h", "--help", "Display this usage summary.").Do(v -> {
help = true;
helpUsage = parser.getUsage();
});
parser.on("--detailed", "Display additional help with -h,--help.").Do(v -> {
helpDetailed = true;
});
parser.on("-A (.ext|prefix.):(-|analyzer)", "--analyzer", "/(\\.\\w+|\\w+\\.):(-|[a-zA-Z_0-9.]+)/", "Files with the named prefix/extension should be analyzed", "with the given analyzer, where 'analyzer' may be specified", "using a simple class name (CAnalyzer) or language name (C)", "(Note, analyzer specification is case sensitive)", " Ex: -A .foo:CAnalyzer", " will use the C analyzer for all files ending with .foo", " Ex: -A bar.:C", " will use the C analyzer for all files starting with bar.", " Ex: -A .c:-", " will disable the C analyzer for for all files ending with .c").Do(analyzerSpec -> {
String[] arg = ((String) analyzerSpec).split(":");
String fileSpec = arg[0];
String analyzer = arg[1];
configureFileAnalyzer(fileSpec, analyzer);
});
parser.on("-c", "--ctags", "=/path/to/ctags", "Path to Exuberant or Universal Ctags", "By default takes the Exuberant Ctags in PATH.").Do(ctagsPath -> {
cfg.setCtags((String) ctagsPath);
});
parser.on("-d", "--dataRoot", "=/path/to/data/root", "The directory where OpenGrok stores the generated data.").Do(drPath -> {
File dataRoot = new File((String) drPath);
if (!dataRoot.exists() && !dataRoot.mkdirs()) {
die("Cannot create data root: " + dataRoot);
}
if (!dataRoot.isDirectory()) {
die("Data root must be a directory");
}
try {
cfg.setDataRoot(dataRoot.getCanonicalPath());
} catch (IOException e) {
die(e.getMessage());
}
});
parser.on("--deleteHistory", "=/path/to/repository", "Delete the history cache for the given repository and exit.", "Use '*' to delete the cache for all repositories.").Do(repo -> {
zapCache.add((String) repo);
});
parser.on("--depth", "=number", Integer.class, "Scanning depth for repositories in directory structure relative to", "source root. Default is " + Configuration.defaultScanningDepth + ".").Do(depth -> {
cfg.setScanningDepth((Integer) depth);
});
parser.on("-e", "--economical", "Economical, consumes less disk space.", "It does not generate hyper text cross reference files offline,", "but will do so on demand, which could be sightly slow.").Do(v -> {
cfg.setGenerateHtml(false);
});
parser.on("-G", "--assignTags", "Assign commit tags to all entries in history for all repositories.").Do(v -> {
cfg.setTagsEnabled(true);
});
parser.on("-H", "--history", "=[/path/to/repository]", "Get history for specific repositories (specified as", "absolute path from source root), or ALL repositories", "when none specified.").Do(repo -> {
String repository = (String) repo;
if (repository.equals("")) {
// all repositories
cfg.setHistoryEnabled(true);
} else {
// specific repository
repositories.add((String) repository);
}
});
parser.on("-I", "--include", "=pattern", "Only files matching this pattern will be examined.", "(supports wildcards, example: -I *.java -I *.c)").Do(pattern -> {
cfg.getIncludedNames().add((String) pattern);
});
parser.on("-i", "--ignore", "=pattern", "Ignore the named files (prefixed with 'f:')", "or directories (prefixed with 'd:').", "Supports wildcards (example: -i *.so -i *.dll)").Do(pattern -> {
cfg.getIgnoredNames().add((String) pattern);
});
parser.on("-l", "--lock", "=on|off|simple|native", LUCENE_LOCKS, "Set OpenGrok/Lucene locking mode of the Lucene database", "during index generation. \"on\" is an alias for \"simple\".", "Default is off.").Do(v -> {
try {
if (v != null) {
String vuc = v.toString().toUpperCase(Locale.ROOT);
cfg.setLuceneLocking(LuceneLockName.valueOf(vuc));
}
} catch (IllegalArgumentException e) {
System.err.println(String.format("`--lock %s' is invalid and ignored", v));
}
});
parser.on("--leadingWildCards", "=on|off", ON_OFF, Boolean.class, "Allow or disallow leading wildcards in a search.").Do(v -> {
cfg.setAllowLeadingWildcard((Boolean) v);
});
parser.on("--listRepos", "List all repository paths and exit.").Do(v -> {
listRepos = true;
});
parser.on("-m", "--memory", "=number", Double.class, "Amount of memory that may be used for buffering added documents and", "deletions before they are flushed to the directory (default " + Configuration.defaultRamBufferSize + "MB).", "Please increase JVM heap accordingly, too.").Do(memSize -> {
cfg.setRamBufferSize((Double) memSize);
});
parser.on("--man", "Generate OpenGrok XML manual page.").Do(v -> {
try {
System.out.print(parser.getManPage());
} catch (IOException e) {
System.err.println(e.getMessage());
status = 1;
}
System.exit(status);
});
parser.on("--mandoc", "=/path/to/mandoc", "Path to mandoc(1) binary.").Do(mandocPath -> {
cfg.setMandoc((String) mandocPath);
});
parser.on("-n", "--noIndex", "Do not generate indexes, but process all other command line options.").Do(v -> {
runIndex = false;
});
parser.on("-O", "--optimize", "=on|off", ON_OFF, Boolean.class, "Turn on/off the optimization of the index database", "as part of the indexing step.").Do(v -> {
boolean oldval = cfg.isOptimizeDatabase();
cfg.setOptimizeDatabase((Boolean) v);
if (oldval != cfg.isOptimizeDatabase()) {
optimizedChanged = true;
}
});
parser.on("-o", "--ctagOpts", "=path", "File with extra command line options for ctags.").Do(path -> {
String CTagsExtraOptionsFile = (String) path;
File CTagsFile = new File(CTagsExtraOptionsFile);
if (!(CTagsFile.isFile() && CTagsFile.canRead())) {
die("File '" + CTagsExtraOptionsFile + "' not found for the -o option");
}
System.err.println("INFO: file with extra " + "options for ctags: " + CTagsExtraOptionsFile);
cfg.setCTagsExtraOptionsFile(CTagsExtraOptionsFile);
});
parser.on("-P", "--projects", "Generate a project for each top-level directory in source root.").Do(v -> {
addProjects = true;
cfg.setProjectsEnabled(true);
});
parser.on("-p", "--defaultProject", "=/path/to/default/project", "This is the path to the project that should be selected", "by default in the web application (when no other project", "set either in cookie or in parameter). May be used multiple", "times for several projects. Use \"__all__\" for all projects.", "You should strip off the source root.").Do(v -> {
defaultProjects.add((String) v);
});
parser.on("--profiler", "Pause to await profiler or debugger.").Do(v -> awaitProfiler = true);
parser.on("--progress", "Print per project percentage progress information.", "(I/O extensive, since one read through directory structure is", "made before indexing, needs -v, otherwise it just goes to the log)").Do(v -> {
cfg.setPrintProgress(true);
});
parser.on("-Q", "--quickScan", "=on|off", ON_OFF, Boolean.class, "Turn on/off quick context scan. By default, only the first", "1024k of a file is scanned, and a '[..all..]' link is inserted", "when the file is bigger. Activating this may slow the server down.", "(Note: this is setting only affects the web application)").Do(v -> {
cfg.setQuickContextScan((Boolean) v);
});
parser.on("-q", "--quiet", "Run as quietly as possible.").Do(v -> {
cfg.setVerbose(false);
LoggerUtil.setBaseConsoleLogLevel(Level.WARNING);
});
parser.on("-R /path/to/configuration", "Read configuration from the specified file.").Do(v -> {
// Already handled above. This populates usage.
});
parser.on("-r", "--remote", "=on|off|uionly|dirbased", REMOTE_REPO_CHOICES, "Specify support for remote SCM systems.", " on - allow retrieval for remote SCM systems.", " off - ignore SCM for remote systems.", " uionly - support remote SCM for user interface only.", "dirbased - allow retrieval during history index only for repositories", " which allow getting history for directories.").Do(v -> {
String option = (String) v;
if (option.equalsIgnoreCase(ON)) {
cfg.setRemoteScmSupported(Configuration.RemoteSCM.ON);
} else if (option.equalsIgnoreCase(OFF)) {
cfg.setRemoteScmSupported(Configuration.RemoteSCM.OFF);
} else if (option.equalsIgnoreCase(DIRBASED)) {
cfg.setRemoteScmSupported(Configuration.RemoteSCM.DIRBASED);
} else if (option.equalsIgnoreCase(UIONLY)) {
cfg.setRemoteScmSupported(Configuration.RemoteSCM.UIONLY);
}
});
parser.on("--renamedHistory", "=on|off", ON_OFF, Boolean.class, "Enable or disable generating history for renamed files.", "If set to on, makes history indexing slower for repositories", "with lots of renamed files.").Do(v -> {
cfg.setHandleHistoryOfRenamedFiles((Boolean) v);
});
parser.on("-S", "--search", "Search for \"external\" source repositories and add them.").Do(v -> {
searchRepositories = true;
});
parser.on("-s", "--source", "=/path/to/source/root", "The root directory of the source tree.").Do(source -> {
File sourceRoot = new File((String) source);
if (!sourceRoot.isDirectory()) {
die("Source root " + sourceRoot + " must be a directory");
}
try {
cfg.setSourceRoot(sourceRoot.getCanonicalPath());
} catch (IOException e) {
die(e.getMessage());
}
});
parser.on("--style", "=path", "Path to the subdirectory in the web-application containing the", "requested stylesheet. The factory-setting is: \"default\".").Do(stylePath -> {
cfg.setWebappLAF((String) stylePath);
});
parser.on("--symlink", "=/path/to/symlink", "Allow this symlink to be followed. Option may be repeated.", "By default only symlinks directly under source root directory", "are allowed.").Do(symlink -> {
allowedSymlinks.add((String) symlink);
});
parser.on("-T", "--threads", "=number", Integer.class, "The number of threads to use for index generation.", "By default the number of threads will be set to the number", "of available CPUs.").Do(threadCount -> {
cfg.setIndexingParallelism((Integer) threadCount);
});
parser.on("-t", "--tabSize", "=number", Integer.class, "Default tab size to use (number of spaces per tab character).").Do(tabSize -> {
cfg.setTabSize((Integer) tabSize);
});
parser.on("-U", "--host", "=host:port", WebAddress.class, "Send the current configuration to the specified address", "(This is most likely the web-app configured with ConfigAddress)").Do(webAddr -> {
WebAddress web = (WebAddress) webAddr;
env = RuntimeEnvironment.getInstance();
host = web.getHost();
port = web.getPort();
env.setConfigHost(host);
env.setConfigPort(port);
});
// For unit test only, will not appear in help
parser.on("---unitTest");
parser.on("--updateConfig", "Populate the webapp with bare configuration and exit.").Do(v -> {
noindex = true;
});
parser.on("--userPage", "=URL", "Base URL of the user Information provider.", "Example: \"http://www.myserver.org/viewProfile.jspa?username=\".", "Use \"none\" to disable link.").Do(v -> {
cfg.setUserPage((String) v);
});
parser.on("--userPageSuffix", "=URL-suffix", "URL Suffix for the user Information provider. Default: \"\".").Do(suffix -> {
cfg.setUserPageSuffix((String) suffix);
});
parser.on("-V", "--version", "Print version and quit.").Do(v -> {
System.out.println(Info.getFullVersion());
System.exit(0);
});
parser.on("-v", "--verbose", "Print progress information as we go along.").Do(v -> {
cfg.setVerbose(true);
LoggerUtil.setBaseConsoleLogLevel(Level.INFO);
});
parser.on("-W", "--writeConfig", "=/path/to/configuration", "Write the current configuration to the specified file", "(so that the web application can use the same configuration)").Do(configFile -> {
configFilename = (String) configFile;
});
parser.on("-w", "--web", "=webapp-context", "Context of webapp. Default is /source. If you specify a different", "name, make sure to rename source.war to that name. Also FULL reindex", "is needed if this is changed.").Do(webContext -> {
String webapp = (String) webContext;
if (webapp.charAt(0) != '/' && !webapp.startsWith("http")) {
webapp = "/" + webapp;
}
if (!webapp.endsWith("/")) {
webapp += "/";
}
cfg.setUrlPrefix(webapp + "s?");
});
});
// Need to read the configuration file first
// so that options may be overwritten later.
configure.parse(argv);
if (cfg == null) {
cfg = new Configuration();
}
// force user to turn on history capture
cfg.setHistoryEnabled(false);
argv = openGrok.parse(argv);
return argv;
}
Aggregations