Skip to content

Commit

Permalink
upstream: b=master,r=2988468ed6d39b4ad39860ae9b3edd47c25ebc4f,t=2017-…
Browse files Browse the repository at this point in the history
…03-12-1317-36819
  • Loading branch information
sonatype-zion committed Mar 13, 2017
1 parent 92ce845 commit 57cb13f
Show file tree
Hide file tree
Showing 35 changed files with 578 additions and 103 deletions.
2 changes: 1 addition & 1 deletion buildsupport/db/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<packaging>pom</packaging>

<properties>
<orientdb.version>2.2.16</orientdb.version>
<orientdb.version>2.2.SONATYPE-SNAPSHOT</orientdb.version>
<hazelcast.version>3.6.6</hazelcast.version>
</properties>

Expand Down
8 changes: 7 additions & 1 deletion buildsupport/internal/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<sonatype-licensing.version>1.4.3</sonatype-licensing.version>
<clm.dto.model.version>1.5.8-01</clm.dto.model.version>
<insight-brain.version>1.24.0-02</insight-brain.version>
<insight-scanner.version>2.4.3-01</insight-scanner.version>
<insight-scanner.version>2.4.5-SNAPSHOT</insight-scanner.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -101,6 +101,12 @@
<version>${insight-scanner.version}</version>
</dependency>

<dependency>
<groupId>com.sonatype.insight.scan</groupId>
<artifactId>insight-scanner-model</artifactId>
<version>${insight-scanner.version}</version>
</dependency>

<dependency>
<groupId>com.sonatype.insight.scan</groupId>
<artifactId>insight-mock-server</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# - Valid IPv6 Hex Compressed Address
# - Valid Hostname according to RFC-1123
# - Port suffix
# See also HostnameValidator.java and Validator.js for other uses of this regex.
Host=^(((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|\
(\\[(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\])|\
(\\[((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\])|\
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2008-present Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.internal.commands;

import javax.inject.Inject;
import javax.inject.Named;

import org.sonatype.nexus.security.SecurityHelper;

import org.apache.karaf.shell.api.action.Action;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.Option;
import org.apache.shiro.authc.UsernamePasswordToken;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* An action to get a logged in user in the console.
*
* @since 3.3
*/
@Named
@Command(name = "login", scope = "nexus", description = "Put a user in context")
public class LoginAction
implements Action
{
private final SecurityHelper securityHelper;

@Option(name = "-u", aliases = { "--username" }, description = "Username to login with", required = true)
String username;

@Option(name = "-p", aliases = { "--password" }, description = "Password to login with", required = true)
String password;

@Inject
public LoginAction(final SecurityHelper securityHelper) {
this.securityHelper = checkNotNull(securityHelper);
}

@Override
public Object execute() throws Exception {
securityHelper.subject().login(new UsernamePasswordToken(username, password));
return null;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2008-present Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.internal.commands;

import javax.inject.Inject;
import javax.inject.Named;

import org.sonatype.nexus.security.SecurityHelper;

import org.apache.karaf.shell.api.action.Action;
import org.apache.karaf.shell.api.action.Command;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* An action to logout the currently logged in user in the console.
*
* @since 3.3
*/
@Named
@Command(name = "logout", scope = "nexus", description = "Remove a user from context")
public class LogoutAction
implements Action
{
private final SecurityHelper securityHelper;

@Inject
public LogoutAction(final SecurityHelper securityHelper) {
this.securityHelper = checkNotNull(securityHelper);
}

@Override
public Object execute() throws Exception {
securityHelper.subject().logout();
return null;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
import static org.sonatype.nexus.quartz.internal.orient.TriggerEntity.State.PAUSED_BLOCKED;
import static org.sonatype.nexus.quartz.internal.orient.TriggerEntity.State.WAITING;
import static org.sonatype.nexus.scheduling.TaskDescriptorSupport.LIMIT_NODE_KEY;
import static org.sonatype.nexus.scheduling.TaskDescriptorSupport.MULTINODE_KEY;

/**
* Orient {@link JobStore}.
Expand Down Expand Up @@ -1110,9 +1111,11 @@ private TriggerFiredBundle triggerFired(final ODatabaseDocumentTx db, final Oper

// block other triggers for job if concurrent execution is disallowed
if (jobDetail.isConcurrentExectionDisallowed()) {
blockOtherTriggers(db, triggerKey, jobDetail.getKey());
blockOtherTriggers(db, triggerKey, jobDetail);
}

jobDetail.getJobDataMap().clearDirtyFlag(); // clear before handing to quartz

return new TriggerFiredBundle(
jobDetail,
trigger,
Expand All @@ -1133,8 +1136,10 @@ private TriggerFiredBundle triggerFired(final ODatabaseDocumentTx db, final Oper
*/
private void blockOtherTriggers(final ODatabaseDocumentTx db,
final TriggerKey firedTriggerKey,
final JobKey jobKey)
final JobDetail jobDetail)
{
JobKey jobKey = jobDetail.getKey();

log.trace("Blocking other triggers: firedTriggerKey={}, jobKey={}", firedTriggerKey, jobKey);

Iterable<TriggerEntity> matches = triggerEntityAdapter.browseWithPredicate
Expand All @@ -1147,6 +1152,10 @@ private void blockOtherTriggers(final ODatabaseDocumentTx db,
return false;
});

if (isMultiNodeTask(jobDetail)) {
matches = local(matches); // multinode task; each node only needs to block local triggers
}

for (TriggerEntity entity : matches) {
// skip the trigger which was fired
if (firedTriggerKey.equals(entity.getValue().getKey())) {
Expand All @@ -1171,23 +1180,25 @@ public void triggeredJobComplete(final OperableTrigger trigger,
log.debug("Triggered job complete: trigger={}, jobDetail={}, instruction={}", trigger, jobDetail, instruction);

executeAndPropagate(db -> {
TriggerEntity triggerEntity = triggerEntityAdapter.readByKey(db, trigger.getKey());
JobDetailEntity jobDetailEntity = jobDetailEntityAdapter.readByKey(db, jobDetail.getKey());

if (jobDetailEntity != null) {
// save job-data-map if needed
if (jobDetail.isPersistJobDataAfterExecution() && jobDetail.getJobDataMap() != null) {
// back from quartz; save job-data-map if needed
if (jobDetail.getJobDataMap().isDirty() && jobDetail.isPersistJobDataAfterExecution()) {
JobDetailEntity jobDetailEntity = jobDetailEntityAdapter.readByKey(db, jobDetail.getKey());

if (jobDetailEntity != null) {
jobDetailEntity.setValue(jobDetail);
jobDetailEntityAdapter.editEntity(db, jobDetailEntity);
}
}

// unblock triggers if concurrent execution is disallowed
if (jobDetail.isConcurrentExectionDisallowed()) {
unblockTriggers(db, jobDetail.getKey());
signaler.signalSchedulingChange(0L);
}
// unblock triggers if concurrent execution is disallowed
if (jobDetail.isConcurrentExectionDisallowed()) {
unblockTriggers(db, jobDetail);
signaler.signalSchedulingChange(0L);
}

TriggerEntity triggerEntity = triggerEntityAdapter.readByKey(db, trigger.getKey());

if (triggerEntity != null) {
switch (instruction) {
case DELETE_TRIGGER:
Expand Down Expand Up @@ -1236,7 +1247,9 @@ public void triggeredJobComplete(final OperableTrigger trigger,
*
* @see #triggeredJobComplete
*/
private void unblockTriggers(final ODatabaseDocumentTx db, final JobKey jobKey) {
private void unblockTriggers(final ODatabaseDocumentTx db, final JobDetail jobDetail) {
JobKey jobKey = jobDetail.getKey();

log.trace("Unblock triggers: jobKey={}", jobKey);

Iterable<TriggerEntity> matches = triggerEntityAdapter.browseWithPredicate
Expand All @@ -1249,6 +1262,10 @@ private void unblockTriggers(final ODatabaseDocumentTx db, final JobKey jobKey)
return false;
});

if (isMultiNodeTask(jobDetail)) {
matches = local(matches); // multinode task; each node only needs to unblock local triggers
}

for (TriggerEntity entity : matches) {
if (entity.getState() == PAUSED_BLOCKED) {
entity.setState(PAUSED);
Expand Down Expand Up @@ -1453,4 +1470,11 @@ private boolean isLimitedToMissingNode(final OperableTrigger trigger) {
}
return false;
}

/**
* Identifies multinode tasks (tasks that explicitly run triggers on all nodes at once).
*/
private boolean isMultiNodeTask(final JobDetail jobDetail) {
return jobDetail.getJobDataMap().getBoolean(MULTINODE_KEY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.quartz.DisallowConcurrentExecution;
import org.quartz.InterruptableJob;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
Expand Down Expand Up @@ -145,7 +146,7 @@ private void doExecute() throws Exception {
}
finally {
// put back any state task modified to have it persisted
context.getJobDetail().getJobDataMap().putAll(task.taskConfiguration().asMap());
updateJobData(context.getJobDetail(), task.taskConfiguration());
}
}
}
Expand Down Expand Up @@ -287,4 +288,16 @@ public static TaskConfiguration configurationOf(final JobDetail jobDetail) {
}
return config;
}

/**
* Saves {@link TaskConfiguration} back to the given {@link JobDetail}.
*/
private static void updateJobData(final JobDetail jobDetail, final TaskConfiguration taskConfiguration) {
JobDataMap jobDataMap = jobDetail.getJobDataMap();
taskConfiguration.asMap().forEach((key, value) -> {
if (!value.equals(jobDataMap.get(key))) {
jobDataMap.put(key, value); // only touch jobDataMap if value actually changed
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* under the License.
*/

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;
Expand All @@ -37,6 +38,8 @@
import org.sonatype.nexus.orient.testsupport.DatabaseInstanceRule;

import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
Expand All @@ -50,9 +53,11 @@
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.ObjectAlreadyExistsException;
import org.quartz.PersistJobDataAfterExecution;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.Trigger.CompletedExecutionInstruction;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
Expand All @@ -64,6 +69,9 @@
import org.quartz.spi.OperableTrigger;
import org.quartz.spi.SchedulerSignaler;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -570,6 +578,37 @@ public void testAcquireTriggersInBatch() throws Exception {
}
}

@Test
public void jobDataOnlySavedWhenDirty() throws Exception {
JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("testJob").build();
OperableTrigger trigger = (OperableTrigger) TriggerBuilder.newTrigger().withIdentity("testJob").forJob(job).build();
jobStore.storeJobAndTrigger(job, trigger);

int baseRecordVersion = queryJobDetail("testJob").getVersion();

// same job data after trigger fired...
jobStore.triggersFired(Arrays.asList(trigger));
jobStore.triggeredJobComplete(trigger, job, CompletedExecutionInstruction.NOOP);

// ...should not save the job
assertThat(queryJobDetail("testJob").getVersion(), is(baseRecordVersion));

// different job data after trigger fired...
jobStore.triggersFired(Arrays.asList(trigger));
job.getJobDataMap().put("testKey", "testValue");
jobStore.triggeredJobComplete(trigger, job, CompletedExecutionInstruction.NOOP);

// ...should save the job
assertThat(queryJobDetail("testJob").getVersion(), greaterThan(baseRecordVersion));
}

private ODocument queryJobDetail(final String name) {
try (ODatabaseDocumentTx db = database.getInstance().acquire()) {
String selectJob = "select from quartz_job_detail where name=?";
return (ODocument) db.query(new OSQLSynchQuery<>(selectJob), name).get(0);
}
}

public static class SampleSignaler
implements SchedulerSignaler
{
Expand All @@ -596,6 +635,7 @@ public void notifySchedulerListenersError(String string, SchedulerException jpe)
/**
* An empty job for testing purpose.
*/
@PersistJobDataAfterExecution
public static class MyJob
implements Job
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ Ext.define('NX.app.PluginStrings', {

// Field validation messages
Util_Validator_Text: 'Only letters, digits, underscores(_), hyphens(-), and dots(.) are allowed and may not start with underscore or dot.',
Util_Validator_Hostname: 'Hostname must be valid',

// Wizard
Wizard_Next: '@Button_Next',
Expand Down
Loading

0 comments on commit 57cb13f

Please sign in to comment.