import org.sonar.server.platform.monitoring.SettingsMonitor;
import org.sonar.server.platform.monitoring.SonarQubeMonitor;
import org.sonar.server.platform.monitoring.SystemMonitor;
-import org.sonar.server.platform.web.requestid.HttpRequestUidModule;
+import org.sonar.server.platform.web.requestid.HttpRequestIdModule;
import org.sonar.server.platform.ws.ChangeLogLevelAction;
import org.sonar.server.platform.ws.DbMigrationStatusAction;
import org.sonar.server.platform.ws.InfoAction;
// webhooks
WebhooksWsModule.class,
- // Http Request UID
- HttpRequestUidModule.class);
+ // Http Request ID
+ HttpRequestIdModule.class);
addAll(level4AddedComponents);
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+import org.sonar.core.platform.Module;
+
+public class HttpRequestIdModule extends Module {
+ @Override
+ protected void configureModule() {
+ add(new RequestIdConfiguration(RequestIdGeneratorImpl.UUID_GENERATOR_RENEWAL_COUNT),
+ RequestIdGeneratorBaseImpl.class,
+ RequestIdGeneratorImpl.class);
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-import org.sonar.core.platform.Module;
-
-public class HttpRequestUidModule extends Module {
- @Override
- protected void configureModule() {
- add(new RequestIdConfiguration(RequestUidGeneratorImpl.UUID_GENERATOR_RENEWAL_COUNT),
- RequestUidGeneratorBaseImpl.class,
- RequestUidGeneratorImpl.class);
- }
-}
public class RequestIdConfiguration {
/**
- * @see RequestUidGeneratorImpl#mustRenewUuidGenerator(long)
+ * @see RequestIdGeneratorImpl#mustRenewUuidGenerator(long)
*/
private final long uuidGeneratorRenewalCount;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+import com.google.common.annotations.VisibleForTesting;
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import org.sonar.server.platform.Platform;
+
+/**
+ * A {@link Filter} that puts and removes the HTTP request ID from the {@link org.slf4j.MDC}.
+ */
+public class RequestIdFilter implements Filter {
+ private final Platform platform;
+
+ public RequestIdFilter() {
+ this(Platform.getInstance());
+ }
+
+ @VisibleForTesting
+ RequestIdFilter(Platform platform) {
+ this.platform = platform;
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ // nothing to do
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ RequestIdGenerator requestIdGenerator = platform.getContainer().getComponentByType(RequestIdGenerator.class);
+
+ try (RequestIdMDCStorage mdcStorage = new RequestIdMDCStorage(requestIdGenerator.generate())) {
+ chain.doFilter(request, response);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ // nothing to do
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+/**
+ * Generate a Unique Identifier for Http Requests.
+ */
+public interface RequestIdGenerator {
+ /**
+ * Generate a new and unique request id for each call.
+ */
+ String generate();
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+import org.sonar.core.util.UuidGenerator;
+
+public interface RequestIdGeneratorBase {
+ /**
+ * Provides a new instance of {@link UuidGenerator.WithFixedBase} to be used by {@link RequestIdGeneratorImpl}.
+ */
+ UuidGenerator.WithFixedBase createNew();
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+import org.sonar.core.util.UuidGenerator;
+import org.sonar.core.util.UuidGeneratorImpl;
+
+public class RequestIdGeneratorBaseImpl implements RequestIdGeneratorBase {
+
+ @Override
+ public UuidGenerator.WithFixedBase createNew() {
+ return new UuidGeneratorImpl().withFixedBase();
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+import java.util.Base64;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+import org.sonar.core.util.UuidGenerator;
+
+/**
+ * This implementation of {@link RequestIdGenerator} creates unique identifiers for HTTP requests leveraging
+ * {@link UuidGenerator.WithFixedBase#generate(int)} and a counter of HTTP requests.
+ * <p>
+ * To work around the limit of unique values produced by {@link UuidGenerator.WithFixedBase#generate(int)}, the
+ * {@link UuidGenerator.WithFixedBase} instance will be renewed every
+ * {@link RequestIdConfiguration#getUidGeneratorRenewalCount() RequestIdConfiguration#uidGeneratorRenewalCount}
+ * HTTP requests.
+ * </p>
+ * <p>
+ * This implementation is Thread safe.
+ * </p>
+ */
+public class RequestIdGeneratorImpl implements RequestIdGenerator {
+ /**
+ * The value to which the HTTP request count will be compared to (using a modulo operator,
+ * see {@link #mustRenewUuidGenerator(long)}).
+ *
+ * <p>
+ * This value can't be the last value before {@link UuidGenerator.WithFixedBase#generate(int)} returns a non unique
+ * value, ie. 2^23-1 because there is no guarantee the renewal will happen before any other thread calls
+ * {@link UuidGenerator.WithFixedBase#generate(int)} method of the deplated {@link UuidGenerator.WithFixedBase} instance.
+ * </p>
+ *
+ * <p>
+ * To keep a comfortable margin of error, 2^22 will be used.
+ * </p>
+ */
+ public static final long UUID_GENERATOR_RENEWAL_COUNT = 4_194_304;
+
+ private final AtomicLong counter = new AtomicLong();
+ private final RequestIdGeneratorBase requestIdGeneratorBase;
+ private final RequestIdConfiguration requestIdConfiguration;
+ private final AtomicReference<UuidGenerator.WithFixedBase> uuidGenerator;
+
+ public RequestIdGeneratorImpl(RequestIdGeneratorBase requestIdGeneratorBase, RequestIdConfiguration requestIdConfiguration) {
+ this.requestIdGeneratorBase = requestIdGeneratorBase;
+ this.uuidGenerator = new AtomicReference<>(requestIdGeneratorBase.createNew());
+ this.requestIdConfiguration = requestIdConfiguration;
+ }
+
+ @Override
+ public String generate() {
+ UuidGenerator.WithFixedBase currentUuidGenerator = this.uuidGenerator.get();
+ long counterValue = counter.getAndIncrement();
+ if (counterValue != 0 && mustRenewUuidGenerator(counterValue)) {
+ UuidGenerator.WithFixedBase newUuidGenerator = requestIdGeneratorBase.createNew();
+ uuidGenerator.set(newUuidGenerator);
+ return generate(newUuidGenerator, counterValue);
+ }
+ return generate(currentUuidGenerator, counterValue);
+ }
+
+ /**
+ * Since renewal of {@link UuidGenerator.WithFixedBase} instance is based on the HTTP request counter, only a single
+ * thread can get the right value which will make this method return true. So, this is thread-safe by design, therefor
+ * this method doesn't need external synchronization.
+ * <p>
+ * The value to which the counter is compared should however be chosen with caution: see {@link #UUID_GENERATOR_RENEWAL_COUNT}.
+ * </p>
+ */
+ private boolean mustRenewUuidGenerator(long counter) {
+ return counter % requestIdConfiguration.getUidGeneratorRenewalCount() == 0;
+ }
+
+ private static String generate(UuidGenerator.WithFixedBase uuidGenerator, long increment) {
+ return Base64.getEncoder().encodeToString(uuidGenerator.generate((int) increment));
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+import org.slf4j.MDC;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Wraps MDC calls to store the HTTP request ID in the {@link MDC} into an {@link AutoCloseable}.
+ */
+class RequestIdMDCStorage implements AutoCloseable {
+ private static final String HTTP_REQUEST_ID_MDC_KEY = "HTTP_REQUEST_ID";
+
+ public RequestIdMDCStorage(String requestId) {
+ MDC.put(HTTP_REQUEST_ID_MDC_KEY, requireNonNull(requestId, "Request ID can't be null"));
+ }
+
+ @Override
+ public void close() {
+ MDC.remove(HTTP_REQUEST_ID_MDC_KEY);
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import org.sonar.server.platform.Platform;
-
-/**
- * A {@link Filter} that puts and removes the HTTP request UID from the {@link org.slf4j.MDC}.
- */
-public class RequestUidFilter implements Filter {
- private final Platform platform;
-
- public RequestUidFilter() {
- this(Platform.getInstance());
- }
-
- @VisibleForTesting
- RequestUidFilter(Platform platform) {
- this.platform = platform;
- }
-
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- // nothing to do
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- RequestUidGenerator requestUidGenerator = platform.getContainer().getComponentByType(RequestUidGenerator.class);
-
- try (RequestUidMDCStorage mdcStorage = new RequestUidMDCStorage(requestUidGenerator.generate())) {
- chain.doFilter(request, response);
- }
- }
-
- @Override
- public void destroy() {
- // nothing to do
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-/**
- * Generate a Unique Identifier for Http Requests.
- */
-public interface RequestUidGenerator {
- /**
- * Generate a new and unique request id for each call.
- */
- String generate();
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-import org.sonar.core.util.UuidGenerator;
-
-public interface RequestUidGeneratorBase {
- /**
- * Provides a new instance of {@link UuidGenerator.WithFixedBase} to be used by {@link RequestUidGeneratorImpl}.
- */
- UuidGenerator.WithFixedBase createNew();
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-import org.sonar.core.util.UuidGenerator;
-import org.sonar.core.util.UuidGeneratorImpl;
-
-public class RequestUidGeneratorBaseImpl implements RequestUidGeneratorBase {
-
- @Override
- public UuidGenerator.WithFixedBase createNew() {
- return new UuidGeneratorImpl().withFixedBase();
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-import java.util.Base64;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-import org.sonar.core.util.UuidGenerator;
-
-/**
- * This implementation of {@link RequestUidGenerator} creates unique identifiers for HTTP requests leveraging
- * {@link UuidGenerator.WithFixedBase#generate(int)} and a counter of HTTP requests.
- * <p>
- * To work around the limit of unique values produced by {@link UuidGenerator.WithFixedBase#generate(int)}, the
- * {@link UuidGenerator.WithFixedBase} instance will be renewed every
- * {@link RequestIdConfiguration#getUidGeneratorRenewalCount() RequestIdConfiguration#uidGeneratorRenewalCount}
- * HTTP requests.
- * </p>
- * <p>
- * This implementation is Thread safe.
- * </p>
- */
-public class RequestUidGeneratorImpl implements RequestUidGenerator {
- /**
- * The value to which the HTTP request count will be compared to (using a modulo operator,
- * see {@link #mustRenewUuidGenerator(long)}).
- *
- * <p>
- * This value can't be the last value before {@link UuidGenerator.WithFixedBase#generate(int)} returns a non unique
- * value, ie. 2^23-1 because there is no guarantee the renewal will happen before any other thread calls
- * {@link UuidGenerator.WithFixedBase#generate(int)} method of the deplated {@link UuidGenerator.WithFixedBase} instance.
- * </p>
- *
- * <p>
- * To keep a comfortable margin of error, 2^22 will be used.
- * </p>
- */
- public static final long UUID_GENERATOR_RENEWAL_COUNT = 4_194_304;
-
- private final AtomicLong counter = new AtomicLong();
- private final RequestUidGeneratorBase requestUidGeneratorBase;
- private final RequestIdConfiguration requestIdConfiguration;
- private final AtomicReference<UuidGenerator.WithFixedBase> uuidGenerator;
-
- public RequestUidGeneratorImpl(RequestUidGeneratorBase requestUidGeneratorBase, RequestIdConfiguration requestIdConfiguration) {
- this.requestUidGeneratorBase = requestUidGeneratorBase;
- this.uuidGenerator = new AtomicReference<>(requestUidGeneratorBase.createNew());
- this.requestIdConfiguration = requestIdConfiguration;
- }
-
- @Override
- public String generate() {
- UuidGenerator.WithFixedBase currentUuidGenerator = this.uuidGenerator.get();
- long counterValue = counter.getAndIncrement();
- if (counterValue != 0 && mustRenewUuidGenerator(counterValue)) {
- UuidGenerator.WithFixedBase newUuidGenerator = requestUidGeneratorBase.createNew();
- uuidGenerator.set(newUuidGenerator);
- return generate(newUuidGenerator, counterValue);
- }
- return generate(currentUuidGenerator, counterValue);
- }
-
- /**
- * Since renewal of {@link UuidGenerator.WithFixedBase} instance is based on the HTTP request counter, only a single
- * thread can get the right value which will make this method return true. So, this is thread-safe by design, therefor
- * this method doesn't need external synchronization.
- * <p>
- * The value to which the counter is compared should however be chosen with caution: see {@link #UUID_GENERATOR_RENEWAL_COUNT}.
- * </p>
- */
- private boolean mustRenewUuidGenerator(long counter) {
- return counter % requestIdConfiguration.getUidGeneratorRenewalCount() == 0;
- }
-
- private static String generate(UuidGenerator.WithFixedBase uuidGenerator, long increment) {
- return Base64.getEncoder().encodeToString(uuidGenerator.generate((int) increment));
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-import org.slf4j.MDC;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * Wraps MDC calls to store the HTTP request UID in the {@link MDC} into an {@link AutoCloseable}.
- */
-class RequestUidMDCStorage implements AutoCloseable {
- private static final String HTTP_REQUEST_UID_MDC_KEY = "HTTP_REQUEST_ID";
-
- public RequestUidMDCStorage(String requestUid) {
- MDC.put(HTTP_REQUEST_UID_MDC_KEY, requireNonNull(requestUid, "Request UID can't be null"));
- }
-
- @Override
- public void close() {
- MDC.remove(HTTP_REQUEST_UID_MDC_KEY);
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+import org.junit.Test;
+import org.sonar.core.platform.ComponentContainer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class HttpRequestIdModuleTest {
+ private static final int COMPONENTS_HARDCODED_IN_CONTAINER = 2;
+
+ private HttpRequestIdModule underTest = new HttpRequestIdModule();
+
+ @Test
+ public void count_components_in_module() {
+ ComponentContainer container = new ComponentContainer();
+ underTest.configure(container);
+
+ assertThat(container.getPicoContainer().getComponentAdapters())
+ .hasSize(COMPONENTS_HARDCODED_IN_CONTAINER + 3);
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-import org.junit.Test;
-import org.sonar.core.platform.ComponentContainer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class HttpRequestUidModuleTest {
- private static final int COMPONENTS_HARDCODED_IN_CONTAINER = 2;
-
- private HttpRequestUidModule underTest = new HttpRequestUidModule();
-
- @Test
- public void count_components_in_module() {
- ComponentContainer container = new ComponentContainer();
- underTest.configure(container);
-
- assertThat(container.getPicoContainer().getComponentAdapters())
- .hasSize(COMPONENTS_HARDCODED_IN_CONTAINER + 3);
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.core.util.UuidGenerator;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class RequestIdGeneratorImplTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private UuidGenerator.WithFixedBase generator1 = increment -> new byte[] {124, 22, 66, 96, 55, 88, 2, 9};
+ private UuidGenerator.WithFixedBase generator2 = increment -> new byte[] {0, 5, 88, 81, 8, 6, 44, 19};
+ private UuidGenerator.WithFixedBase generator3 = increment -> new byte[] {126, 9, 35, 76, 2, 1, 2};
+ private RequestIdGeneratorBase uidGeneratorBase = mock(RequestIdGeneratorBase.class);
+ private IllegalStateException expected = new IllegalStateException("Unexpected third call to createNew");
+
+ @Test
+ public void generate_renews_inner_UuidGenerator_instance_every_number_of_calls_to_generate_specified_in_RequestIdConfiguration_supports_2() {
+ when(uidGeneratorBase.createNew())
+ .thenReturn(generator1)
+ .thenReturn(generator2)
+ .thenReturn(generator3)
+ .thenThrow(expected);
+
+ RequestIdGeneratorImpl underTest = new RequestIdGeneratorImpl(uidGeneratorBase, new RequestIdConfiguration(2));
+
+ assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // using generator1
+ assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // still using generator1
+ assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // renewing generator and using generator2
+ assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // still using generator2
+ assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // renewing generator and using generator3
+ assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // using generator3
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage(expected.getMessage());
+
+ underTest.generate(); // renewing generator and failing
+ }
+
+ @Test
+ public void generate_renews_inner_UuidGenerator_instance_every_number_of_calls_to_generate_specified_in_RequestIdConfiguration_supports_3() {
+ when(uidGeneratorBase.createNew())
+ .thenReturn(generator1)
+ .thenReturn(generator2)
+ .thenReturn(generator3)
+ .thenThrow(expected);
+
+ RequestIdGeneratorImpl underTest = new RequestIdGeneratorImpl(uidGeneratorBase, new RequestIdConfiguration(3));
+
+ assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // using generator1
+ assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // still using generator1
+ assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // still using generator1
+ assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // renewing generator and using it
+ assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // still using generator2
+ assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // still using generator2
+ assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // renewing generator and using it
+ assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // using generator3
+ assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // using generator3
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage(expected.getMessage());
+
+ underTest.generate(); // renewing generator and failing
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.web.requestid;
+
+import org.apache.log4j.MDC;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RequestIdMDCStorageTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @After
+ public void tearDown() throws Exception {
+ MDC.clear();
+ }
+
+ @Test
+ public void constructor_fails_with_NPE_when_argument_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("Request ID can't be null");
+
+ new RequestIdMDCStorage(null);
+ }
+
+ @Test
+ public void constructor_adds_specified_value_in_MDC_under_HTTP_REQUEST_ID_key() {
+ new RequestIdMDCStorage("toto");
+
+ assertThat(MDC.get("HTTP_REQUEST_ID")).isEqualTo("toto");
+ }
+
+ @Test
+ public void close_removes_value_from_MDC() {
+ RequestIdMDCStorage underTest = new RequestIdMDCStorage("boum");
+ assertThat(MDC.get("HTTP_REQUEST_ID")).isEqualTo("boum");
+
+ underTest.close();
+
+ assertThat(MDC.get("HTTP_REQUEST_ID")).isNull();
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.core.util.UuidGenerator;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class RequestUidGeneratorImplTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private UuidGenerator.WithFixedBase generator1 = increment -> new byte[] {124, 22, 66, 96, 55, 88, 2, 9};
- private UuidGenerator.WithFixedBase generator2 = increment -> new byte[] {0, 5, 88, 81, 8, 6, 44, 19};
- private UuidGenerator.WithFixedBase generator3 = increment -> new byte[] {126, 9, 35, 76, 2, 1, 2};
- private RequestUidGeneratorBase uidGeneratorBase = mock(RequestUidGeneratorBase.class);
- private IllegalStateException expected = new IllegalStateException("Unexpected third call to createNew");
-
- @Test
- public void generate_renews_inner_UuidGenerator_instance_every_number_of_calls_to_generate_specified_in_RequestIdConfiguration_supports_2() {
- when(uidGeneratorBase.createNew())
- .thenReturn(generator1)
- .thenReturn(generator2)
- .thenReturn(generator3)
- .thenThrow(expected);
-
- RequestUidGeneratorImpl underTest = new RequestUidGeneratorImpl(uidGeneratorBase, new RequestIdConfiguration(2));
-
- assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // using generator1
- assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // still using generator1
- assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // renewing generator and using generator2
- assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // still using generator2
- assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // renewing generator and using generator3
- assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // using generator3
-
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage(expected.getMessage());
-
- underTest.generate(); // renewing generator and failing
- }
-
- @Test
- public void generate_renews_inner_UuidGenerator_instance_every_number_of_calls_to_generate_specified_in_RequestIdConfiguration_supports_3() {
- when(uidGeneratorBase.createNew())
- .thenReturn(generator1)
- .thenReturn(generator2)
- .thenReturn(generator3)
- .thenThrow(expected);
-
- RequestUidGeneratorImpl underTest = new RequestUidGeneratorImpl(uidGeneratorBase, new RequestIdConfiguration(3));
-
- assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // using generator1
- assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // still using generator1
- assertThat(underTest.generate()).isEqualTo("fBZCYDdYAgk="); // still using generator1
- assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // renewing generator and using it
- assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // still using generator2
- assertThat(underTest.generate()).isEqualTo("AAVYUQgGLBM="); // still using generator2
- assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // renewing generator and using it
- assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // using generator3
- assertThat(underTest.generate()).isEqualTo("fgkjTAIBAg=="); // using generator3
-
- expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage(expected.getMessage());
-
- underTest.generate(); // renewing generator and failing
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.platform.web.requestid;
-
-import org.apache.log4j.MDC;
-import org.junit.After;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class RequestUidMDCStorageTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- @After
- public void tearDown() throws Exception {
- MDC.clear();
- }
-
- @Test
- public void constructor_fails_with_NPE_when_argument_is_null() {
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("Request UID can't be null");
-
- new RequestUidMDCStorage(null);
- }
-
- @Test
- public void constructor_adds_specified_value_in_MDC_under_HTTP_REQUEST_ID_key() {
- new RequestUidMDCStorage("toto");
-
- assertThat(MDC.get("HTTP_REQUEST_ID")).isEqualTo("toto");
- }
-
- @Test
- public void close_removes_value_from_MDC() {
- RequestUidMDCStorage underTest = new RequestUidMDCStorage("boum");
- assertThat(MDC.get("HTTP_REQUEST_ID")).isEqualTo("boum");
-
- underTest.close();
-
- assertThat(MDC.get("HTTP_REQUEST_ID")).isNull();
- }
-}
</filter>
<filter>
<filter-name>RequestUidFilter</filter-name>
- <filter-class>org.sonar.server.platform.web.requestid.RequestUidFilter</filter-class>
+ <filter-class>org.sonar.server.platform.web.requestid.RequestIdFilter</filter-class>
</filter>
<!-- order of execution is important -->