mirror of https://github.com/longtai-cn/hippo4j
feat: Implement blocking queue SPI extension and add documentation (#1612)
* Add BlockingQueueManager * Remove hardcoded queues * Add queue extension and switching test code * Add a custom queue documents * Update queue switching description * fix: upgrade Mockito to 4.11.0 * optimize ThreadPoolRebuilder * Add custom SPI blocking queue type support * fix: Enable inline mock maker to support static mocks * Apply default capacity for custom queue types * Remove ThreadPoolRebuilder runtime queue switching * Clarify responsibilities and eliminate redundancy in BlockingQueueManager * rollback mockito version to 3.12.4 * Update frontend static files with custom queue support * Allow passing queue capacity to custom blocking queue SPIdevelop
parent
7d78be3cab
commit
9aa3be0750
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache 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://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 cn.hippo4j.common.executor.support;
|
||||
|
||||
import cn.hippo4j.common.extension.spi.ServiceLoaderRegistry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* Blocking queue runtime manager.
|
||||
* Provides queue management operations: capacity adjustment, type recognition, and configuration validation.
|
||||
*
|
||||
* <p>Note: For queue creation, use {@link BlockingQueueTypeEnum#createBlockingQueue(int, Integer)}
|
||||
* or {@link BlockingQueueTypeEnum#createBlockingQueue(String, Integer)} directly.</p>
|
||||
*/
|
||||
@Slf4j
|
||||
public class BlockingQueueManager {
|
||||
|
||||
/**
|
||||
* Check if queue capacity can be dynamically changed
|
||||
*
|
||||
* @param currentQueue current queue instance
|
||||
* @return true if capacity can be changed
|
||||
*/
|
||||
public static boolean canChangeCapacity(BlockingQueue<?> currentQueue) {
|
||||
if (currentQueue == null) {
|
||||
return false;
|
||||
}
|
||||
// Only ResizableCapacityLinkedBlockingQueue supports capacity change
|
||||
return currentQueue instanceof ResizableCapacityLinkedBlockingQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change queue capacity if supported
|
||||
*
|
||||
* @param currentQueue current queue instance
|
||||
* @param newCapacity new capacity
|
||||
* @return true if capacity was changed
|
||||
*/
|
||||
public static boolean changeQueueCapacity(BlockingQueue<?> currentQueue, Integer newCapacity) {
|
||||
if (!canChangeCapacity(currentQueue) || newCapacity == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (currentQueue instanceof ResizableCapacityLinkedBlockingQueue) {
|
||||
ResizableCapacityLinkedBlockingQueue<?> resizableQueue =
|
||||
(ResizableCapacityLinkedBlockingQueue<?>) currentQueue;
|
||||
resizableQueue.setCapacity(newCapacity);
|
||||
log.debug("Queue capacity changed to: {}", newCapacity);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to change queue capacity to: {}", newCapacity, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get queue type from queue instance
|
||||
*
|
||||
* @param queue queue instance
|
||||
* @return queue type, null if not found
|
||||
*/
|
||||
public static Integer getQueueType(BlockingQueue<?> queue) {
|
||||
if (queue == null) {
|
||||
return null;
|
||||
}
|
||||
String queueName = queue.getClass().getSimpleName();
|
||||
for (BlockingQueueTypeEnum typeEnum : BlockingQueueTypeEnum.values()) {
|
||||
if (Objects.equals(typeEnum.getName(), queueName)) {
|
||||
return typeEnum.getType();
|
||||
}
|
||||
}
|
||||
Collection<CustomBlockingQueue> customQueues = ServiceLoaderRegistry
|
||||
.getSingletonServiceInstances(CustomBlockingQueue.class);
|
||||
for (CustomBlockingQueue customQueue : customQueues) {
|
||||
if (Objects.equals(customQueue.getName(), queueName)) {
|
||||
return customQueue.getType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get queue name from queue instance
|
||||
*
|
||||
* @param queue queue instance
|
||||
* @return queue name
|
||||
*/
|
||||
public static String getQueueName(BlockingQueue<?> queue) {
|
||||
if (queue == null) {
|
||||
return "Unknown";
|
||||
}
|
||||
return queue.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate queue configuration
|
||||
*
|
||||
* @param queueType queue type
|
||||
* @param capacity queue capacity
|
||||
* @return validation result
|
||||
*/
|
||||
public static boolean validateQueueConfig(Integer queueType, Integer capacity) {
|
||||
if (queueType == null) {
|
||||
return false;
|
||||
}
|
||||
String queueName = BlockingQueueTypeEnum.getBlockingQueueNameByType(queueType);
|
||||
if (queueName.isEmpty()) {
|
||||
Collection<CustomBlockingQueue> customQueues = ServiceLoaderRegistry
|
||||
.getSingletonServiceInstances(CustomBlockingQueue.class);
|
||||
boolean found = customQueues.stream()
|
||||
.anyMatch(customQueue -> Objects.equals(customQueue.getType(), queueType));
|
||||
if (!found) {
|
||||
log.warn("Invalid queue type: {}", queueType);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (capacity != null && capacity <= 0) {
|
||||
if (queueType.equals(BlockingQueueTypeEnum.SYNCHRONOUS_QUEUE.getType()) ||
|
||||
queueType.equals(BlockingQueueTypeEnum.LINKED_TRANSFER_QUEUE.getType())) {
|
||||
return true;
|
||||
}
|
||||
log.warn("Invalid capacity: {} for queue type: {}", capacity, queueType);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache 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://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 cn.hippo4j.common.executor.integration;
|
||||
|
||||
import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum;
|
||||
import cn.hippo4j.common.executor.support.CustomBlockingQueue;
|
||||
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Queue SPI Integration Test: Verifies the full flow from parameters to queue creation
|
||||
* This test simulates a real scenario:
|
||||
* 1. Config center pushes queue configuration (queueType, capacity)
|
||||
* 2. Thread pool is created with the specified queue type
|
||||
* 3. BlockingQueueTypeEnum.createBlockingQueue() calls SPI loader
|
||||
* 4. Custom queues can be used via SPI mechanism
|
||||
*/
|
||||
public class QueueSpiIntegrationTest {
|
||||
|
||||
/**
|
||||
* Custom queue for SPI testing
|
||||
*/
|
||||
public static class IntegrationTestQueue implements CustomBlockingQueue<Runnable> {
|
||||
|
||||
private static final AtomicInteger LAST_REQUESTED_CAPACITY = new AtomicInteger();
|
||||
|
||||
@Override
|
||||
public Integer getType() {
|
||||
return 20001; // Integration test specific type ID
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "IntegrationTestQueue";
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockingQueue<Runnable> generateBlockingQueue() {
|
||||
return generateBlockingQueue(256);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockingQueue<Runnable> generateBlockingQueue(Integer capacity) {
|
||||
int effectiveCapacity = capacity == null || capacity <= 0 ? 1024 : capacity;
|
||||
LAST_REQUESTED_CAPACITY.set(effectiveCapacity);
|
||||
return new ArrayBlockingQueue<>(effectiveCapacity);
|
||||
}
|
||||
|
||||
public static int getLastRequestedCapacity() {
|
||||
return LAST_REQUESTED_CAPACITY.get();
|
||||
}
|
||||
|
||||
public static void resetLastRequestedCapacity() {
|
||||
LAST_REQUESTED_CAPACITY.set(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario 1: Verify that ThreadPoolParameterInfo can carry queueType
|
||||
*/
|
||||
@Test
|
||||
public void testParameterCarriesQueueType() {
|
||||
System.out.println("========== Integration Test Scenario 1: Parameter carries queueType ==========");
|
||||
|
||||
ThreadPoolParameterInfo parameter = new ThreadPoolParameterInfo();
|
||||
parameter.setTenantId("default");
|
||||
parameter.setItemId("item-001");
|
||||
parameter.setTpId("test-pool");
|
||||
parameter.setQueueType(2); // LinkedBlockingQueue
|
||||
parameter.setCapacity(1024);
|
||||
|
||||
Assert.assertNotNull("queueType should be set", parameter.getQueueType());
|
||||
Assert.assertEquals("queueType should be 2", Integer.valueOf(2), parameter.getQueueType());
|
||||
Assert.assertEquals("capacity should be 1024", Integer.valueOf(1024), parameter.getCapacity());
|
||||
|
||||
System.out.println("ThreadPoolParameterInfo can carry queueType and capacity");
|
||||
System.out.println(" queueType: " + parameter.getQueueType());
|
||||
System.out.println(" capacity: " + parameter.getCapacity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario 2: Verify built-in queues can be created via type ID
|
||||
*/
|
||||
@Test
|
||||
public void testBuiltInQueueCreationViaTypeId() {
|
||||
System.out.println("\n========== Integration Test Scenario 2: Built-in queue creation ==========");
|
||||
|
||||
BlockingQueue<Runnable> arrayQueue = BlockingQueueTypeEnum.createBlockingQueue(1, 512);
|
||||
Assert.assertNotNull("ArrayBlockingQueue should be created", arrayQueue);
|
||||
Assert.assertTrue("Should be instance of ArrayBlockingQueue", arrayQueue instanceof ArrayBlockingQueue);
|
||||
|
||||
BlockingQueue<Runnable> linkedQueue = BlockingQueueTypeEnum.createBlockingQueue(2, 1024);
|
||||
Assert.assertNotNull("LinkedBlockingQueue should be created", linkedQueue);
|
||||
Assert.assertTrue("Should be instance of LinkedBlockingQueue", linkedQueue instanceof LinkedBlockingQueue);
|
||||
|
||||
System.out.println("Built-in queue types can be created by type ID");
|
||||
System.out.println(" Type 1 (ArrayBlockingQueue): " + arrayQueue.getClass().getSimpleName());
|
||||
System.out.println(" Type 2 (LinkedBlockingQueue): " + linkedQueue.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario 3: Verify SPI queues can be created via type ID
|
||||
*/
|
||||
@Test
|
||||
public void testSpiQueueCreationViaTypeId() {
|
||||
System.out.println("\n========== Integration Test Scenario 3: SPI queue creation ==========");
|
||||
|
||||
BlockingQueue<Runnable> spiQueue = BlockingQueueTypeEnum.createBlockingQueue(10001, 512);
|
||||
Assert.assertNotNull("SPI custom queue should be created", spiQueue);
|
||||
Assert.assertTrue("Should be instance of ArrayBlockingQueue (TestCustomQueue implementation)",
|
||||
spiQueue instanceof ArrayBlockingQueue);
|
||||
Assert.assertEquals("Custom queue capacity should match server value", 512, spiQueue.remainingCapacity());
|
||||
|
||||
QueueSpiIntegrationTest.IntegrationTestQueue.resetLastRequestedCapacity();
|
||||
BlockingQueue<Runnable> integrationQueue = BlockingQueueTypeEnum.createBlockingQueue(20001, 2048);
|
||||
Assert.assertNotNull("Integration test custom queue should be created", integrationQueue);
|
||||
Assert.assertTrue("Integration queue should be ArrayBlockingQueue", integrationQueue instanceof ArrayBlockingQueue);
|
||||
Assert.assertEquals("Integration queue capacity should honor config", 2048, integrationQueue.remainingCapacity());
|
||||
Assert.assertEquals("Integration custom queue should receive normalized capacity", 2048,
|
||||
QueueSpiIntegrationTest.IntegrationTestQueue.getLastRequestedCapacity());
|
||||
|
||||
System.out.println("SPI queue can be created via type ID");
|
||||
System.out.println(" Type 10001 (TestCustomQueue): " + spiQueue.getClass().getSimpleName());
|
||||
System.out.println(" Queue capacity: " + spiQueue.remainingCapacity());
|
||||
System.out.println(" Type 20001 (IntegrationTestQueue): " + integrationQueue.getClass().getSimpleName());
|
||||
System.out.println(" Queue capacity: " + integrationQueue.remainingCapacity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario 4: Simulate the complete queue switch flow
|
||||
*/
|
||||
@Test
|
||||
public void testCompleteQueueSwitchFlow() {
|
||||
System.out.println("\n========== Integration Test Scenario 4: Complete queue switch flow ==========");
|
||||
|
||||
ThreadPoolParameterInfo newParameter = new ThreadPoolParameterInfo();
|
||||
newParameter.setTenantId("default");
|
||||
newParameter.setItemId("item-001");
|
||||
newParameter.setTpId("test-pool");
|
||||
newParameter.setQueueType(20001); // Switch to IntegrationTestQueue
|
||||
newParameter.setCapacity(768);
|
||||
|
||||
System.out.println("Step 1: Config pushed - queueType=" + newParameter.getQueueType());
|
||||
|
||||
boolean queueTypeChanged = newParameter.getQueueType() != null;
|
||||
Assert.assertTrue("Should detect queue type change", queueTypeChanged);
|
||||
System.out.println("Step 2: Detected queue type change");
|
||||
|
||||
IntegrationTestQueue.resetLastRequestedCapacity();
|
||||
BlockingQueue<Runnable> newQueue = BlockingQueueTypeEnum.createBlockingQueue(
|
||||
newParameter.getQueueType(),
|
||||
newParameter.getCapacity());
|
||||
Assert.assertNotNull("New queue should be created", newQueue);
|
||||
System.out.println("Step 3: New queue created - " + newQueue.getClass().getSimpleName());
|
||||
|
||||
Assert.assertTrue("New queue should be SPI custom implementation (ArrayBlockingQueue)",
|
||||
newQueue instanceof ArrayBlockingQueue);
|
||||
Assert.assertEquals("New queue capacity should be 768", 768, newQueue.remainingCapacity());
|
||||
Assert.assertEquals("Custom queue should see normalized capacity", 768,
|
||||
IntegrationTestQueue.getLastRequestedCapacity());
|
||||
System.out.println("Step 4: Verified new queue - Type: ArrayBlockingQueue, Capacity: 768");
|
||||
|
||||
System.out.println("Complete queue creation flow verified");
|
||||
System.out.println("Proves: Config → BlockingQueueTypeEnum → SPI → Custom Queue");
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario 5: Verify queue switching does not depend on hardcoded logic
|
||||
*/
|
||||
@Test
|
||||
public void testQueueSwitchNotHardcoded() {
|
||||
System.out.println("\n========== Integration Test Scenario 5: Queue switch not hardcoded ==========");
|
||||
|
||||
int[] queueTypes = {1, 2, 3, 9, 10001, 20001};
|
||||
for (int queueType : queueTypes) {
|
||||
BlockingQueue<Runnable> queue = BlockingQueueTypeEnum.createBlockingQueue(queueType, 512);
|
||||
Assert.assertNotNull("Queue type " + queueType + " should be created", queue);
|
||||
System.out.println("Queue type " + queueType + " created: " + queue.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
System.out.println("Queue switching is not hardcoded, supports any type (built-in + SPI)");
|
||||
System.out.println("Proves: ServerThreadPoolDynamicRefresh.handleQueueChanges() removed hardcoded restriction");
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario 6: Verify consistency with rejection policy
|
||||
*/
|
||||
@Test
|
||||
public void testConsistencyWithRejectedPolicy() {
|
||||
System.out.println("\n========== Integration Test Scenario 6: Consistency with rejected policy ==========");
|
||||
|
||||
ThreadPoolParameterInfo parameter = new ThreadPoolParameterInfo();
|
||||
parameter.setRejectedType(1); // AbortPolicy
|
||||
parameter.setQueueType(20001); // SPI custom queue (IntegrationTestQueue)
|
||||
parameter.setCapacity(640);
|
||||
|
||||
BlockingQueue<Runnable> queue = BlockingQueueTypeEnum.createBlockingQueue(
|
||||
parameter.getQueueType(),
|
||||
parameter.getCapacity());
|
||||
Assert.assertNotNull("Queue should be created", queue);
|
||||
Assert.assertEquals("Queue should reflect configured capacity", 640, queue.remainingCapacity());
|
||||
Assert.assertEquals("Integration queue should receive normalized capacity", 640,
|
||||
IntegrationTestQueue.getLastRequestedCapacity());
|
||||
|
||||
System.out.println("Rejected policy and blocking queue design are consistent:");
|
||||
System.out.println(" - Rejected policy: created dynamically via type ID (rejectedType)");
|
||||
System.out.println(" - Blocking queue: created dynamically via type ID (queueType)");
|
||||
System.out.println(" - Both support SPI extensions");
|
||||
System.out.println("Verified: ServerThreadPoolDynamicRefresh supports SPI extension for both rejection policy and queues");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache 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://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 cn.hippo4j.common.executor.support;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Blocking Queue SPI Test: Verify that custom queues can be supported via SPI just like rejection policies
|
||||
*/
|
||||
public class BlockingQueueSpiTest {
|
||||
|
||||
/**
|
||||
* Test custom queue SPI implementation
|
||||
* Note: SPI mechanism creates instances via no-arg constructor,
|
||||
* capacity is dynamically passed in generateBlockingQueue
|
||||
*/
|
||||
public static class TestCustomQueue implements CustomBlockingQueue<Runnable> {
|
||||
|
||||
private static final int DEFAULT_CAPACITY = 512;
|
||||
|
||||
private static final AtomicReference<Integer> LAST_REQUESTED_CAPACITY = new AtomicReference<>();
|
||||
|
||||
@Override
|
||||
public Integer getType() {
|
||||
return 10001; // Custom type ID
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "TestCustomQueue";
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockingQueue<Runnable> generateBlockingQueue() {
|
||||
return generateBlockingQueue(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockingQueue<Runnable> generateBlockingQueue(Integer capacity) {
|
||||
int effectiveCapacity = capacity == null || capacity <= 0 ? DEFAULT_CAPACITY : capacity;
|
||||
LAST_REQUESTED_CAPACITY.set(effectiveCapacity);
|
||||
return new ArrayBlockingQueue<>(effectiveCapacity);
|
||||
}
|
||||
|
||||
public static Integer getLastRequestedCapacity() {
|
||||
return LAST_REQUESTED_CAPACITY.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 1: SPI interface definition integrity
|
||||
*/
|
||||
@Test
|
||||
public void testSpiInterfaceDefinition() {
|
||||
System.out.println("========== Test Case 1: SPI interface definition integrity ==========");
|
||||
|
||||
TestCustomQueue customQueue = new TestCustomQueue();
|
||||
|
||||
// Verify interface methods
|
||||
Assert.assertNotNull("getType() should return non-null type ID", customQueue.getType());
|
||||
Assert.assertEquals("Type ID should be 10001", Integer.valueOf(10001), customQueue.getType());
|
||||
Assert.assertEquals("getName() should return queue name", "TestCustomQueue", customQueue.getName());
|
||||
|
||||
BlockingQueue<Runnable> queue = customQueue.generateBlockingQueue();
|
||||
Assert.assertNotNull("generateBlockingQueue() should return non-null queue", queue);
|
||||
Assert.assertTrue("Should return ArrayBlockingQueue instance", queue instanceof ArrayBlockingQueue);
|
||||
Assert.assertEquals("Queue capacity should be 512", 512, queue.remainingCapacity());
|
||||
|
||||
System.out.println("Custom queue type ID: " + customQueue.getType());
|
||||
System.out.println("Custom queue name: " + customQueue.getName());
|
||||
System.out.println("Generated queue type: " + queue.getClass().getSimpleName());
|
||||
System.out.println("Queue capacity: " + queue.remainingCapacity());
|
||||
System.out.println("Passed: SPI interface definition is complete");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 1.5: SPI configuration file registration validation
|
||||
* Verify custom queue is correctly registered via SPI config file
|
||||
*/
|
||||
@Test
|
||||
public void testSpiConfigurationRegistration() {
|
||||
System.out.println("\n========== Test Case 1.5: SPI configuration file registration validation ==========");
|
||||
|
||||
System.out.println("SPI config file location: src/test/resources/META-INF/services/cn.hippo4j.common.executor.support.CustomBlockingQueue");
|
||||
System.out.println("SPI config content: cn.hippo4j.common.executor.support.BlockingQueueSpiTest$TestCustomQueue");
|
||||
|
||||
// Create custom queue via SPI mechanism (type ID 10001)
|
||||
BlockingQueue<Runnable> spiQueue = BlockingQueueTypeEnum.createBlockingQueue(10001, 512);
|
||||
Assert.assertNotNull("Should successfully create custom queue via SPI", spiQueue);
|
||||
|
||||
// Verify it's created by SPI TestCustomQueue implementation
|
||||
Assert.assertTrue("Should create ArrayBlockingQueue instance (TestCustomQueue implementation)",
|
||||
spiQueue instanceof ArrayBlockingQueue);
|
||||
Assert.assertEquals("Queue capacity should be 512", 512, spiQueue.remainingCapacity());
|
||||
Assert.assertEquals("Custom queue should receive requested capacity", Integer.valueOf(512), TestCustomQueue.getLastRequestedCapacity());
|
||||
|
||||
System.out.println("Successfully created custom queue via SPI type ID 10001");
|
||||
System.out.println("Queue type: " + spiQueue.getClass().getSimpleName());
|
||||
System.out.println("Queue capacity: " + spiQueue.remainingCapacity());
|
||||
System.out.println("Passed: SPI configuration registration works");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 2: Built-in queue type creation
|
||||
*/
|
||||
@Test
|
||||
public void testBuiltInQueueCreation() {
|
||||
System.out.println("\n========== Test Case 2: Built-in queue type creation ==========");
|
||||
|
||||
// Test all built-in queue types
|
||||
BlockingQueue<Runnable> arrayQueue = BlockingQueueTypeEnum.createBlockingQueue(1, 1024);
|
||||
Assert.assertTrue("Type 1 should create ArrayBlockingQueue", arrayQueue instanceof ArrayBlockingQueue);
|
||||
System.out.println("Type 1 (ArrayBlockingQueue): " + arrayQueue.getClass().getSimpleName());
|
||||
|
||||
BlockingQueue<Runnable> linkedQueue = BlockingQueueTypeEnum.createBlockingQueue(2, 1024);
|
||||
Assert.assertTrue("Type 2 should create LinkedBlockingQueue", linkedQueue instanceof LinkedBlockingQueue);
|
||||
System.out.println("Type 2 (LinkedBlockingQueue): " + linkedQueue.getClass().getSimpleName());
|
||||
|
||||
BlockingQueue<Runnable> deque = BlockingQueueTypeEnum.createBlockingQueue(3, 1024);
|
||||
Assert.assertNotNull("Type 3 should create LinkedBlockingDeque", deque);
|
||||
System.out.println("Type 3 (LinkedBlockingDeque): " + deque.getClass().getSimpleName());
|
||||
|
||||
BlockingQueue<Runnable> syncQueue = BlockingQueueTypeEnum.createBlockingQueue(4, null);
|
||||
Assert.assertNotNull("Type 4 should create SynchronousQueue", syncQueue);
|
||||
System.out.println("Type 4 (SynchronousQueue): " + syncQueue.getClass().getSimpleName());
|
||||
|
||||
BlockingQueue<Runnable> priorityQueue = BlockingQueueTypeEnum.createBlockingQueue(5, 1024);
|
||||
Assert.assertNotNull("Type 5 should create PriorityBlockingQueue", priorityQueue);
|
||||
System.out.println("Type 5 (PriorityBlockingQueue): " + priorityQueue.getClass().getSimpleName());
|
||||
|
||||
BlockingQueue<Runnable> resizableQueue = BlockingQueueTypeEnum.createBlockingQueue(9, 1024);
|
||||
Assert.assertNotNull("Type 9 should create ResizableCapacityLinkedBlockingQueue", resizableQueue);
|
||||
System.out.println("Type 9 (ResizableCapacityLinkedBlockingQueue): " + resizableQueue.getClass().getSimpleName());
|
||||
|
||||
System.out.println("Passed: All built-in queue types created successfully");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 3: Queue creation via BlockingQueueTypeEnum
|
||||
*/
|
||||
@Test
|
||||
public void testBlockingQueueCreation() {
|
||||
System.out.println("\n========== Test Case 3: Queue creation via BlockingQueueTypeEnum ==========");
|
||||
|
||||
// Create built-in queue via BlockingQueueTypeEnum
|
||||
BlockingQueue<Runnable> queue1 = BlockingQueueTypeEnum.createBlockingQueue(1, 512);
|
||||
Assert.assertNotNull("Should successfully create queue", queue1);
|
||||
Assert.assertTrue("Should create ArrayBlockingQueue", queue1 instanceof ArrayBlockingQueue);
|
||||
|
||||
// Create by type name
|
||||
BlockingQueue<Runnable> queue2 = BlockingQueueTypeEnum.createBlockingQueue("ArrayBlockingQueue", 1024);
|
||||
Assert.assertNotNull("Should successfully create queue by name", queue2);
|
||||
Assert.assertTrue("Should create ArrayBlockingQueue", queue2 instanceof ArrayBlockingQueue);
|
||||
|
||||
// Test default queue with null type - falls back to LinkedBlockingQueue
|
||||
BlockingQueue<Runnable> defaultQueue = BlockingQueueTypeEnum.createBlockingQueue("", 1024);
|
||||
Assert.assertNotNull("Empty name should create default queue", defaultQueue);
|
||||
System.out.println("Default queue type: " + defaultQueue.getClass().getSimpleName());
|
||||
|
||||
System.out.println("Passed: BlockingQueueTypeEnum queue creation works");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 3.5: SPI queue default capacity when config missing
|
||||
*/
|
||||
@Test
|
||||
public void testSpiQueueDefaultCapacity() {
|
||||
System.out.println("\n========== Test Case 3.5: SPI queue default capacity ==========");
|
||||
|
||||
BlockingQueue<Runnable> queue = BlockingQueueTypeEnum.createBlockingQueue(10001, null);
|
||||
Assert.assertNotNull("Should create custom queue when capacity missing", queue);
|
||||
Assert.assertTrue("Should still be ArrayBlockingQueue", queue instanceof ArrayBlockingQueue);
|
||||
Assert.assertEquals("Default capacity should fallback to 1024", 1024, queue.remainingCapacity());
|
||||
Assert.assertEquals("Custom queue should receive normalized capacity", Integer.valueOf(1024), TestCustomQueue.getLastRequestedCapacity());
|
||||
|
||||
System.out.println("SPI queue default capacity -> " + queue.remainingCapacity());
|
||||
System.out.println("Passed: Custom queue receives normalized capacity");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 4: Queue type recognition
|
||||
*/
|
||||
@Test
|
||||
public void testQueueTypeRecognition() {
|
||||
System.out.println("\n========== Test Case 4: Queue type recognition ==========");
|
||||
|
||||
BlockingQueue<Runnable> arrayQueue = new ArrayBlockingQueue<>(256);
|
||||
Integer type1 = BlockingQueueManager.getQueueType(arrayQueue);
|
||||
System.out.println("ArrayBlockingQueue recognized type: " + type1);
|
||||
Assert.assertEquals("Should be recognized as type 1", Integer.valueOf(1), type1);
|
||||
|
||||
BlockingQueue<Runnable> linkedQueue = new LinkedBlockingQueue<>(512);
|
||||
Integer type2 = BlockingQueueManager.getQueueType(linkedQueue);
|
||||
System.out.println("LinkedBlockingQueue recognized type: " + type2);
|
||||
Assert.assertEquals("Should be recognized as type 2", Integer.valueOf(2), type2);
|
||||
|
||||
String name1 = BlockingQueueManager.getQueueName(arrayQueue);
|
||||
System.out.println("ArrayBlockingQueue queue name: " + name1);
|
||||
Assert.assertEquals("Should return correct name", "ArrayBlockingQueue", name1);
|
||||
|
||||
System.out.println("Passed: Queue type recognition works");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 5: Queue config validation
|
||||
*/
|
||||
@Test
|
||||
public void testQueueConfigValidation() {
|
||||
System.out.println("\n========== Test Case 5: Queue config validation ==========");
|
||||
|
||||
// Valid config
|
||||
boolean valid1 = BlockingQueueManager.validateQueueConfig(1, 1024);
|
||||
Assert.assertTrue("ArrayBlockingQueue config should be valid", valid1);
|
||||
System.out.println("ArrayBlockingQueue (type=1, capacity=1024): " + (valid1 ? "valid" : "invalid"));
|
||||
|
||||
// SynchronousQueue does not need capacity
|
||||
boolean valid2 = BlockingQueueManager.validateQueueConfig(4, null);
|
||||
Assert.assertTrue("SynchronousQueue without capacity should be valid", valid2);
|
||||
System.out.println("SynchronousQueue (type=4, capacity=null): " + (valid2 ? "valid" : "invalid"));
|
||||
|
||||
// Invalid capacity
|
||||
boolean invalid1 = BlockingQueueManager.validateQueueConfig(1, -1);
|
||||
Assert.assertFalse("Negative capacity should be invalid", invalid1);
|
||||
System.out.println("ArrayBlockingQueue (type=1, capacity=-1): " + (invalid1 ? "valid" : "invalid"));
|
||||
|
||||
// Invalid type
|
||||
boolean invalid2 = BlockingQueueManager.validateQueueConfig(null, 1024);
|
||||
Assert.assertFalse("Null type should be invalid", invalid2);
|
||||
System.out.println("null type: " + (invalid2 ? "valid" : "invalid"));
|
||||
|
||||
System.out.println("Passed: Queue config validation works");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 6: Queue capacity change capability
|
||||
*/
|
||||
@Test
|
||||
public void testQueueCapacityChange() {
|
||||
System.out.println("\n========== Test Case 6: Queue capacity change capability ==========");
|
||||
|
||||
// ResizableCapacityLinkedBlockingQueue supports dynamic resizing
|
||||
BlockingQueue<Runnable> resizableQueue = BlockingQueueTypeEnum.createBlockingQueue(9, 512);
|
||||
boolean canResize = BlockingQueueManager.canChangeCapacity(resizableQueue);
|
||||
System.out.println("ResizableCapacityLinkedBlockingQueue resizable: " + canResize);
|
||||
Assert.assertTrue("ResizableCapacityLinkedBlockingQueue should be resizable", canResize);
|
||||
|
||||
// ArrayBlockingQueue does not support dynamic resizing
|
||||
BlockingQueue<Runnable> arrayQueue = new ArrayBlockingQueue<>(256);
|
||||
boolean cannotResize = BlockingQueueManager.canChangeCapacity(arrayQueue);
|
||||
System.out.println("ArrayBlockingQueue resizable: " + cannotResize);
|
||||
Assert.assertFalse("ArrayBlockingQueue should not be resizable", cannotResize);
|
||||
|
||||
System.out.println("Passed: Queue capacity change capability recognized correctly");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 7: Queue type-name conversion
|
||||
*/
|
||||
@Test
|
||||
public void testQueueTypeNameConversion() {
|
||||
System.out.println("\n========== Test Case 7: Queue type-name conversion ==========");
|
||||
|
||||
// Type to name
|
||||
String name1 = BlockingQueueTypeEnum.getBlockingQueueNameByType(1);
|
||||
Assert.assertEquals("Type 1 should be converted to ArrayBlockingQueue", "ArrayBlockingQueue", name1);
|
||||
System.out.println("Type 1 -> " + name1);
|
||||
|
||||
String name2 = BlockingQueueTypeEnum.getBlockingQueueNameByType(2);
|
||||
Assert.assertEquals("Type 2 should be converted to LinkedBlockingQueue", "LinkedBlockingQueue", name2);
|
||||
System.out.println("Type 2 -> " + name2);
|
||||
|
||||
// Name to type
|
||||
Integer type1 = BlockingQueueTypeEnum.getBlockingQueueTypeEnumByName("ArrayBlockingQueue").getType();
|
||||
Assert.assertEquals("ArrayBlockingQueue should be converted to type 1", Integer.valueOf(1), type1);
|
||||
System.out.println("ArrayBlockingQueue -> " + type1);
|
||||
|
||||
Integer type2 = BlockingQueueTypeEnum.getBlockingQueueTypeEnumByName("LinkedBlockingQueue").getType();
|
||||
Assert.assertEquals("LinkedBlockingQueue should be converted to type 2", Integer.valueOf(2), type2);
|
||||
System.out.println("LinkedBlockingQueue -> " + type2);
|
||||
|
||||
System.out.println("Passed: Queue type-name conversion works");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 8: Queue type comparison (simulate change detection)
|
||||
*/
|
||||
@Test
|
||||
public void testQueueTypeComparison() {
|
||||
System.out.println("\n========== Test Case 8: Queue type change detection ==========");
|
||||
|
||||
BlockingQueue<Runnable> currentQueue = new LinkedBlockingQueue<>(1024);
|
||||
Integer currentType = BlockingQueueManager.getQueueType(currentQueue);
|
||||
|
||||
// Case 1: No change
|
||||
Integer requestedType1 = 2; // LinkedBlockingQueue
|
||||
boolean typeChanged1 = !currentType.equals(requestedType1);
|
||||
System.out.println("Current type: " + currentType + ", Requested: " + requestedType1 + ", Changed: " + typeChanged1);
|
||||
Assert.assertFalse("Same type should not be detected as change", typeChanged1);
|
||||
|
||||
// Case 2: Type changed
|
||||
Integer requestedType2 = 1; // ArrayBlockingQueue
|
||||
boolean typeChanged2 = !currentType.equals(requestedType2);
|
||||
System.out.println("Current type: " + currentType + ", Requested: " + requestedType2 + ", Changed: " + typeChanged2);
|
||||
Assert.assertTrue("Different type should be detected as change", typeChanged2);
|
||||
|
||||
System.out.println("Passed: Queue type change detection works");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 9: Verify queue SPI support consistent with rejection policy SPI
|
||||
*/
|
||||
@Test
|
||||
public void testQueueSpiConsistencyWithRejectedPolicy() {
|
||||
System.out.println("\n========== Test Case 9: Queue SPI consistency with rejection policy ==========");
|
||||
|
||||
// Queue SPI feature validation
|
||||
System.out.println("Queue SPI supported features:");
|
||||
System.out.println("1.SPI interface definition: CustomBlockingQueue");
|
||||
System.out.println("2.Type ID identification: getType() returns unique int ID");
|
||||
System.out.println("3.Name identification: getName() returns queue name");
|
||||
System.out.println("4.Instance creation: generateBlockingQueue() creates queue instance");
|
||||
System.out.println("5.Unified creation entry: BlockingQueueManager.createQueue()");
|
||||
System.out.println("6.Built-in type support: BlockingQueueTypeEnum provides 6 built-in queues");
|
||||
System.out.println("7.SPI extension support: loaded via ServiceLoaderRegistry");
|
||||
System.out.println("8.Type recognition: BlockingQueueManager.getQueueType()");
|
||||
System.out.println("9.Config validation: BlockingQueueManager.validateQueueConfig()");
|
||||
System.out.println("10.Dynamic switching: ServerThreadPoolDynamicRefresh.handleQueueChanges()");
|
||||
|
||||
// Compare with rejection policy
|
||||
System.out.println("\nComparison with Rejection Policy SPI:");
|
||||
System.out.println("Rejection Policy SPI: RejectedExecutionHandler + RejectedPolicyTypeEnum");
|
||||
System.out.println("Queue SPI: CustomBlockingQueue + BlockingQueueTypeEnum");
|
||||
System.out.println("Common features:");
|
||||
System.out.println(" - Unified SPI interface definition");
|
||||
System.out.println(" - Type ID based identification");
|
||||
System.out.println(" - Enum managing built-in types");
|
||||
System.out.println(" - ServiceLoader loading mechanism");
|
||||
System.out.println(" - Unified creation entry");
|
||||
|
||||
System.out.println("Passed: Queue SPI design pattern is consistent with rejection policy");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
cn.hippo4j.common.executor.support.BlockingQueueSpiTest$TestCustomQueue
|
||||
cn.hippo4j.common.executor.integration.QueueSpiIntegrationTest$IntegrationTestQueue
|
||||
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache 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://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 cn.hippo4j.config.service.biz.impl;
|
||||
|
||||
import cn.hippo4j.config.model.ConfigAllInfo;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static cn.hippo4j.common.executor.support.BlockingQueueTypeEnum.*;
|
||||
|
||||
/**
|
||||
* Test for ConfigServiceImpl.getQueueCapacityByType method
|
||||
* Verifies queue capacity handling for both built-in and custom queue types
|
||||
*/
|
||||
public class ConfigServiceQueueCapacityTest {
|
||||
|
||||
private static final int DEFAULT_QUEUE_CAPACITY = 1024;
|
||||
|
||||
/**
|
||||
* Use reflection to invoke private method getQueueCapacityByType
|
||||
*/
|
||||
private Integer invokeGetQueueCapacityByType(ConfigAllInfo config) throws Exception {
|
||||
ConfigServiceImpl configService = new ConfigServiceImpl(null, null, null, null);
|
||||
Method method = ConfigServiceImpl.class.getDeclaredMethod("getQueueCapacityByType", ConfigAllInfo.class);
|
||||
method.setAccessible(true);
|
||||
return (Integer) method.invoke(configService, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 1: Built-in queue with valid capacity
|
||||
* Expected: Return the configured capacity
|
||||
*/
|
||||
@Test
|
||||
public void testBuiltInQueueWithValidCapacity() throws Exception {
|
||||
System.out.println("========== Test Case 1: Built-in queue with valid capacity ==========");
|
||||
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(ARRAY_BLOCKING_QUEUE.getType());
|
||||
config.setCapacity(2048);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("Should return configured capacity", Integer.valueOf(2048), result);
|
||||
System.out.println("Built-in queue with capacity 2048 returns: " + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 2: Built-in queue with null capacity
|
||||
* Expected: Return default capacity (1024)
|
||||
*/
|
||||
@Test
|
||||
public void testBuiltInQueueWithNullCapacity() throws Exception {
|
||||
System.out.println("\n========== Test Case 2: Built-in queue with null capacity ==========");
|
||||
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(LINKED_BLOCKING_QUEUE.getType());
|
||||
config.setCapacity(null);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("Should return default capacity", Integer.valueOf(DEFAULT_QUEUE_CAPACITY), result);
|
||||
System.out.println("Built-in queue with null capacity returns default: " + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 3: Built-in queue with zero capacity
|
||||
* Expected: Return default capacity (1024)
|
||||
*/
|
||||
@Test
|
||||
public void testBuiltInQueueWithZeroCapacity() throws Exception {
|
||||
System.out.println("\n========== Test Case 3: Built-in queue with zero capacity ==========");
|
||||
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(LINKED_BLOCKING_DEQUE.getType());
|
||||
config.setCapacity(0);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("Should return default capacity", Integer.valueOf(DEFAULT_QUEUE_CAPACITY), result);
|
||||
System.out.println("Built-in queue with zero capacity returns default: " + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 4: LinkedTransferQueue with any capacity
|
||||
* Expected: Return Integer.MAX_VALUE (LinkedTransferQueue doesn't support capacity limit)
|
||||
*/
|
||||
@Test
|
||||
public void testLinkedTransferQueueReturnsMaxValue() throws Exception {
|
||||
System.out.println("\n========== Test Case 4: LinkedTransferQueue returns MAX_VALUE ==========");
|
||||
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(LINKED_TRANSFER_QUEUE.getType());
|
||||
config.setCapacity(1024);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("Should return Integer.MAX_VALUE", Integer.valueOf(Integer.MAX_VALUE), result);
|
||||
System.out.println("LinkedTransferQueue returns MAX_VALUE: " + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 5: ResizableLinkedBlockingQueue with valid capacity
|
||||
* Expected: Return the configured capacity
|
||||
*/
|
||||
@Test
|
||||
public void testResizableQueueWithValidCapacity() throws Exception {
|
||||
System.out.println("\n========== Test Case 5: ResizableLinkedBlockingQueue with valid capacity ==========");
|
||||
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(RESIZABLE_LINKED_BLOCKING_QUEUE.getType());
|
||||
config.setCapacity(4096);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("Should return configured capacity", Integer.valueOf(4096), result);
|
||||
System.out.println("ResizableLinkedBlockingQueue with capacity 4096 returns: " + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 6: Custom queue type with valid capacity
|
||||
* Expected: Return the configured capacity
|
||||
*/
|
||||
@Test
|
||||
public void testCustomQueueWithValidCapacity() throws Exception {
|
||||
System.out.println("\n========== Test Case 6: Custom queue with valid capacity ==========");
|
||||
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(10001); // Custom queue type ID
|
||||
config.setCapacity(512);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("Should return configured capacity", Integer.valueOf(512), result);
|
||||
System.out.println("Custom queue with capacity 512 returns: " + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 7: Custom queue type with null capacity
|
||||
* Expected: Return default capacity (1024)
|
||||
* This is the FIX - previously this would return null
|
||||
*/
|
||||
@Test
|
||||
public void testCustomQueueWithNullCapacity() throws Exception {
|
||||
System.out.println("\n========== Test Case 7: Custom queue with null capacity (FIX) ==========");
|
||||
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(10001); // Custom queue type ID
|
||||
config.setCapacity(null);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("Should return default capacity for custom queue",
|
||||
Integer.valueOf(DEFAULT_QUEUE_CAPACITY), result);
|
||||
System.out.println("Custom queue with null capacity returns default: " + result);
|
||||
System.out.println(" This is the FIX - previously would return null!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 8: Custom queue type with zero capacity
|
||||
* Expected: Return default capacity (1024)
|
||||
* This is the FIX - previously this would return 0
|
||||
*/
|
||||
@Test
|
||||
public void testCustomQueueWithZeroCapacity() throws Exception {
|
||||
System.out.println("\n========== Test Case 8: Custom queue with zero capacity (FIX) ==========");
|
||||
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(20001); // Another custom queue type ID
|
||||
config.setCapacity(0);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("Should return default capacity for custom queue",
|
||||
Integer.valueOf(DEFAULT_QUEUE_CAPACITY), result);
|
||||
System.out.println("Custom queue with zero capacity returns default: " + result);
|
||||
System.out.println(" This is the FIX - previously would return 0!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 9: Multiple custom queue types
|
||||
* Expected: All custom queue types should be handled consistently
|
||||
*/
|
||||
@Test
|
||||
public void testMultipleCustomQueueTypes() throws Exception {
|
||||
System.out.println("\n========== Test Case 9: Multiple custom queue types consistency ==========");
|
||||
|
||||
int[] customQueueTypes = {10001, 20001, 30001, 99999};
|
||||
|
||||
for (int queueType : customQueueTypes) {
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(queueType);
|
||||
config.setCapacity(null);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("All custom queues should return default capacity",
|
||||
Integer.valueOf(DEFAULT_QUEUE_CAPACITY), result);
|
||||
System.out.println("Custom queue type " + queueType + " with null capacity returns: " + result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 10: Boundary test - very large capacity
|
||||
* Expected: Return the configured large capacity
|
||||
*/
|
||||
@Test
|
||||
public void testVeryLargeCapacity() throws Exception {
|
||||
System.out.println("\n========== Test Case 10: Very large capacity ==========");
|
||||
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(ARRAY_BLOCKING_QUEUE.getType());
|
||||
config.setCapacity(1000000);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("Should return configured large capacity", Integer.valueOf(1000000), result);
|
||||
System.out.println("Built-in queue with capacity 1000000 returns: " + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case 11: Verify consistency - all built-in queues with null capacity
|
||||
* Expected: All should return default capacity (1024)
|
||||
*/
|
||||
@Test
|
||||
public void testAllBuiltInQueuesWithNullCapacity() throws Exception {
|
||||
System.out.println("\n========== Test Case 11: All built-in queues with null capacity ==========");
|
||||
|
||||
Integer[] builtInQueueTypes = {
|
||||
ARRAY_BLOCKING_QUEUE.getType(),
|
||||
LINKED_BLOCKING_QUEUE.getType(),
|
||||
LINKED_BLOCKING_DEQUE.getType(),
|
||||
PRIORITY_BLOCKING_QUEUE.getType(),
|
||||
RESIZABLE_LINKED_BLOCKING_QUEUE.getType()
|
||||
};
|
||||
|
||||
for (Integer queueType : builtInQueueTypes) {
|
||||
ConfigAllInfo config = new ConfigAllInfo();
|
||||
config.setQueueType(queueType);
|
||||
config.setCapacity(null);
|
||||
|
||||
Integer result = invokeGetQueueCapacityByType(config);
|
||||
|
||||
Assert.assertEquals("All built-in queues should return default capacity",
|
||||
Integer.valueOf(DEFAULT_QUEUE_CAPACITY), result);
|
||||
System.out.println("Queue type " + queueType + " with null capacity returns default: " + result);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.monitor-wrapper[data-v-3957ed61]{width:100%;height:calc(100vh - 50px);display:grid;grid-template-rows:60px 1fr 2fr;grid-template-columns:240px 2fr 1fr;background-color:#ebebf3;gap:10px;padding:10px;-webkit-box-sizing:border-box;box-sizing:border-box}.monitor-wrapper>div[data-v-3957ed61]{border-radius:8px;background-color:#fff;padding:12px}.monitor-wrapper .chart-title[data-v-3957ed61]{font-size:16px;font-weight:bolder;margin:0}.monitor-wrapper .info-wrapper[data-v-3957ed61]::-webkit-scrollbar{display:none}.monitor-wrapper .info-wrapper[data-v-3957ed61]{grid-row:1/4;grid-column:1/2;padding:20rpx;overflow-y:scroll}.monitor-wrapper .info-wrapper .top-card[data-v-3957ed61]{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-pack:distribute;justify-content:space-around;padding:20px 0;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:rgba(67,95,129,.9);font-weight:600}.monitor-wrapper .info-wrapper .top-card .svg-icon[data-v-3957ed61]{width:60px;height:60px;left:0}.monitor-wrapper .info-wrapper .top-card .top-icon[data-v-3957ed61]{width:40px}.monitor-wrapper .info-wrapper .query-monitoring[data-v-3957ed61]{margin-bottom:30px}.monitor-wrapper .info-wrapper .query-monitoring .title[data-v-3957ed61]{padding:0 0 10px 5px;font-weight:600;color:rgba(67,95,129,.9)}.monitor-wrapper .info-wrapper .query-monitoring .el-cascader[data-v-3957ed61]{width:100%}.monitor-wrapper .info-wrapper .info-card[data-v-3957ed61]{background-color:rgba(67,95,129,.9);border-radius:8px;padding:20px;margin-bottom:20px;color:#fefefe;font-family:HelveticaNeue-Medium,Helvetica Medium,PingFangSC-Medium,STHeitiSC-Medium,Microsoft YaHei Bold,Arial,sans-serif}.monitor-wrapper .info-wrapper .info-card .data-num[data-v-3957ed61],.monitor-wrapper .info-wrapper .info-card .info-card-title[data-v-3957ed61]{font-size:14px;font-weight:500;padding-bottom:10px}.monitor-wrapper .info-wrapper .info-card .info-card-show[data-v-3957ed61]{display:none}.monitor-wrapper .info-wrapper .info-card .info-card-item:hover .info-card-show[data-v-3957ed61]{display:block;position:absolute;left:30px;background:#313131;border-radius:4px;padding:5px 8px 6px 8px;-webkit-box-shadow:1px 1px 5px 239;box-shadow:1px 1px 5px 239;z-index:9999}.monitor-wrapper .info-wrapper .info-card .operation-list[data-v-3957ed61]{color:#a9a9a9}.monitor-wrapper .info-wrapper .tp-card[data-v-3957ed61]{border:1px solid #dfe6ec;padding:20px 10px 30px 10px;border-radius:8px;background-color:rgba(67,95,129,.9);color:#fff}.monitor-wrapper .info-wrapper .tp-card .tp-item[data-v-3957ed61]{border-bottom:1px solid #e3e3e3;line-height:40px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-size:14px;-ms-flex-wrap:wrap;flex-wrap:wrap;overflow:hidden}.monitor-wrapper .info-wrapper .tp-card .tp-item .tp-label[data-v-3957ed61]{width:600}.monitor-wrapper .info-wrapper .tp-card .info-card-show[data-v-3957ed61]{display:none}.monitor-wrapper .info-wrapper .tp-card .tp-item:hover .info-card-show[data-v-3957ed61]{display:block;position:absolute;background:#313131;border-radius:4px;padding:5px 8px 6px 8px;-webkit-box-shadow:1px 1px 5px 239;box-shadow:1px 1px 5px 239;z-index:9999}.monitor-wrapper .search-wrapper[data-v-3957ed61]{grid-row:1/2;grid-column:2/4;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.monitor-wrapper .search-wrapper .demonstration[data-v-3957ed61]{margin:0 10px;font-weight:600;color:#3a3b3c}.monitor-wrapper .search-wrapper .button[data-v-3957ed61]{background:rgba(67,95,129,.9);color:#fff;margin-left:20px}.monitor-wrapper .center-chart-wrapper[data-v-3957ed61]{grid-row:2/3;grid-column:2/4}.monitor-wrapper .bottom-chart-wraper[data-v-3957ed61]{grid-row:3/4;grid-column:2/4;display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:24px}.monitor-wrapper .bottom-chart-wraper .inner-chart[data-v-3957ed61]{grid-column:span 1;grid-row:span 1}.monitor-wrapper .bottom-no-wraper[data-v-3957ed61]{width:100%;height:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;font-size:20px;font-weight:600;color:#818689;font-family:Courier New,Courier,monospace}
|
||||
@ -1 +1 @@
|
||||
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.pagination-container[data-v-df7d1fa0]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-df7d1fa0]{display:none}[data-v-a1fe05c0]::-webkit-scrollbar{width:8px;height:8px}[data-v-a1fe05c0]::-webkit-scrollbar-track{border-radius:5px;background:rgba(0,0,0,.06);-webkit-box-shadow:inset 0 0 5px rgba(0,0,0,.08)}[data-v-a1fe05c0]::-webkit-scrollbar-thumb{border-radius:5px;background:rgba(0,0,0,.12);-webkit-box-shadow:inset 0 0 10px rgba(0,0,0,.2)}.stack-info[data-v-a1fe05c0]{height:400px;overflow:auto}.stack-info>li[data-v-a1fe05c0]{margin-bottom:24px}.stack-info>li p[data-v-a1fe05c0]:first-child{color:#06f;font-weight:600;margin-top:10px}.stack-info>li ul[data-v-a1fe05c0]{margin-left:30px}.stack-info>li ul li[data-v-a1fe05c0]{color:#fc5531;text-align:justify;margin:10px auto}
|
||||
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.pagination-container[data-v-df7d1fa0]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-df7d1fa0]{display:none}[data-v-7ec7eb11]::-webkit-scrollbar{width:8px;height:8px}[data-v-7ec7eb11]::-webkit-scrollbar-track{border-radius:5px;background:rgba(0,0,0,.06);-webkit-box-shadow:inset 0 0 5px rgba(0,0,0,.08)}[data-v-7ec7eb11]::-webkit-scrollbar-thumb{border-radius:5px;background:rgba(0,0,0,.12);-webkit-box-shadow:inset 0 0 10px rgba(0,0,0,.2)}.stack-info[data-v-7ec7eb11]{height:400px;overflow:auto}.stack-info>li[data-v-7ec7eb11]{margin-bottom:24px}.stack-info>li p[data-v-7ec7eb11]:first-child{color:#06f;font-weight:600;margin-top:10px}.stack-info>li ul[data-v-7ec7eb11]{margin-left:30px}.stack-info>li ul li[data-v-7ec7eb11]{color:#fc5531;text-align:justify;margin:10px auto}
|
||||
@ -1 +0,0 @@
|
||||
.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.dashboard-editor-container[data-v-5ce168aa]{padding:32px;background-color:#f0f2f5;position:relative;min-height:100vh}
|
||||
@ -1 +1 @@
|
||||
.github-corner:hover .octo-arm[data-v-fedac698]{-webkit-animation:octocat-wave-data-v-fedac698 .56s ease-in-out;animation:octocat-wave-data-v-fedac698 .56s ease-in-out}@-webkit-keyframes octocat-wave-data-v-fedac698{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}@keyframes octocat-wave-data-v-fedac698{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm[data-v-fedac698]{-webkit-animation:none;animation:none}.github-corner .octo-arm[data-v-fedac698]{-webkit-animation:octocat-wave-data-v-fedac698 .56s ease-in-out;animation:octocat-wave-data-v-fedac698 .56s ease-in-out}}.panel-group[data-v-b4165a68]{margin-top:18px}.panel-group .card-panel-col[data-v-b4165a68]{margin-bottom:32px}.panel-group .card-panel[data-v-b4165a68]{height:108px;cursor:pointer;font-size:12px;position:relative;overflow:hidden;color:#666;background:#fff;-webkit-box-shadow:4px 4px 40px rgba(0,0,0,.05);box-shadow:4px 4px 40px rgba(0,0,0,.05);border-color:rgba(0,0,0,.05)}.panel-group .card-panel:hover .card-panel-icon-wrapper[data-v-b4165a68]{color:#fff}.panel-group .card-panel:hover .icon-people[data-v-b4165a68]{background:#dae8d6}.panel-group .card-panel:hover .icon-message[data-v-b4165a68]{background:#36a3f7}.panel-group .card-panel:hover .icon-money[data-v-b4165a68]{background:#a0a6f4}.panel-group .card-panel:hover .icon-shopping[data-v-b4165a68]{background:#dae8d6}.panel-group .card-panel .icon-people[data-v-b4165a68]{color:#40c9c6}.panel-group .card-panel .icon-message[data-v-b4165a68]{color:#36a3f7}.panel-group .card-panel .icon-money[data-v-b4165a68]{color:#a0a6f4}.panel-group .card-panel .icon-shopping[data-v-b4165a68]{color:#34bfa3}.panel-group .card-panel .card-panel-icon-wrapper[data-v-b4165a68]{float:left;margin:14px 0 0 14px;padding:16px;-webkit-transition:all .38s ease-out;transition:all .38s ease-out;border-radius:6px}.panel-group .card-panel .card-panel-icon[data-v-b4165a68]{float:left;font-size:48px}.panel-group .card-panel .card-panel-description[data-v-b4165a68]{float:right;font-weight:700;margin:26px;margin-left:0}.panel-group .card-panel .card-panel-description .card-panel-text[data-v-b4165a68]{line-height:18px;color:rgba(0,0,0,.45);font-size:16px;margin-bottom:12px}.panel-group .card-panel .card-panel-description .card-panel-num[data-v-b4165a68]{font-size:20px}@media(max-width:550px){.card-panel-description[data-v-b4165a68]{display:none}.card-panel-icon-wrapper[data-v-b4165a68]{float:none!important;width:100%;height:100%;margin:0!important}.card-panel-icon-wrapper .svg-icon[data-v-b4165a68]{display:block;margin:14px auto!important;float:none!important}}.dashboard-editor-container[data-v-1cb2dce5]{padding:32px;background-color:#f0f2f5;position:relative}.dashboard-editor-container .github-corner[data-v-1cb2dce5]{position:absolute;top:0;border:0;right:0}.dashboard-editor-container .el-form-item[data-v-1cb2dce5]{margin-bottom:5px!important;padding-bottom:20px}.dashboard-editor-container .chart-wrapper[data-v-1cb2dce5]{background:#fff;padding:16px 16px 0;margin-bottom:32px}@media(max-width:1024px){.chart-wrapper[data-v-1cb2dce5]{padding:8px}}
|
||||
.github-corner:hover .octo-arm[data-v-fedac698]{-webkit-animation:octocat-wave-data-v-fedac698 .56s ease-in-out;animation:octocat-wave-data-v-fedac698 .56s ease-in-out}@-webkit-keyframes octocat-wave-data-v-fedac698{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}@keyframes octocat-wave-data-v-fedac698{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm[data-v-fedac698]{-webkit-animation:none;animation:none}.github-corner .octo-arm[data-v-fedac698]{-webkit-animation:octocat-wave-data-v-fedac698 .56s ease-in-out;animation:octocat-wave-data-v-fedac698 .56s ease-in-out}}.panel-group[data-v-b4165a68]{margin-top:18px}.panel-group .card-panel-col[data-v-b4165a68]{margin-bottom:32px}.panel-group .card-panel[data-v-b4165a68]{height:108px;cursor:pointer;font-size:12px;position:relative;overflow:hidden;color:#666;background:#fff;-webkit-box-shadow:4px 4px 40px rgba(0,0,0,.05);box-shadow:4px 4px 40px rgba(0,0,0,.05);border-color:rgba(0,0,0,.05)}.panel-group .card-panel:hover .card-panel-icon-wrapper[data-v-b4165a68]{color:#fff}.panel-group .card-panel:hover .icon-people[data-v-b4165a68]{background:#dae8d6}.panel-group .card-panel:hover .icon-message[data-v-b4165a68]{background:#36a3f7}.panel-group .card-panel:hover .icon-money[data-v-b4165a68]{background:#a0a6f4}.panel-group .card-panel:hover .icon-shopping[data-v-b4165a68]{background:#dae8d6}.panel-group .card-panel .icon-people[data-v-b4165a68]{color:#40c9c6}.panel-group .card-panel .icon-message[data-v-b4165a68]{color:#36a3f7}.panel-group .card-panel .icon-money[data-v-b4165a68]{color:#a0a6f4}.panel-group .card-panel .icon-shopping[data-v-b4165a68]{color:#34bfa3}.panel-group .card-panel .card-panel-icon-wrapper[data-v-b4165a68]{float:left;margin:14px 0 0 14px;padding:16px;-webkit-transition:all .38s ease-out;transition:all .38s ease-out;border-radius:6px}.panel-group .card-panel .card-panel-icon[data-v-b4165a68]{float:left;font-size:48px}.panel-group .card-panel .card-panel-description[data-v-b4165a68]{float:right;font-weight:700;margin:26px;margin-left:0}.panel-group .card-panel .card-panel-description .card-panel-text[data-v-b4165a68]{line-height:18px;color:rgba(0,0,0,.45);font-size:16px;margin-bottom:12px}.panel-group .card-panel .card-panel-description .card-panel-num[data-v-b4165a68]{font-size:20px}@media(max-width:550px){.card-panel-description[data-v-b4165a68]{display:none}.card-panel-icon-wrapper[data-v-b4165a68]{float:none!important;width:100%;height:100%;margin:0!important}.card-panel-icon-wrapper .svg-icon[data-v-b4165a68]{display:block;margin:14px auto!important;float:none!important}}.dashboard-editor-container[data-v-112b6b2e]{padding:32px;background-color:#f0f2f5;position:relative}.dashboard-editor-container .github-corner[data-v-112b6b2e]{position:absolute;top:0;border:0;right:0}.dashboard-editor-container .el-form-item[data-v-112b6b2e]{margin-bottom:5px!important;padding-bottom:20px}.dashboard-editor-container .chart-wrapper[data-v-112b6b2e]{background:#fff;padding:16px 16px 0;margin-bottom:32px}@media(max-width:1024px){.chart-wrapper[data-v-112b6b2e]{padding:8px}}
|
||||
@ -1 +1 @@
|
||||
.social-signup-container[data-v-7309fbbb]{margin:20px 0}.social-signup-container .sign-btn[data-v-7309fbbb]{display:inline-block;cursor:pointer}.social-signup-container .icon[data-v-7309fbbb]{color:#fff;font-size:24px;margin-top:8px}.social-signup-container .qq-svg-container[data-v-7309fbbb],.social-signup-container .wx-svg-container[data-v-7309fbbb]{display:inline-block;width:40px;height:40px;line-height:40px;text-align:center;padding-top:1px;border-radius:4px;margin-bottom:20px;margin-right:5px}.social-signup-container .wx-svg-container[data-v-7309fbbb]{background-color:#24da70}.social-signup-container .qq-svg-container[data-v-7309fbbb]{background-color:#6ba2d6;margin-left:50px}@supports(-webkit-mask:none) and (not (cater-color:#fff)){.login-container .el-input input{color:#fff}}.login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#fff;height:47px;caret-color:#fff}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #283443 inset!important;box-shadow:inset 0 0 0 1000px #283443!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container[data-v-c62df1a8]{min-height:100%;width:100%;background-color:#2d3a4b;overflow:hidden}.login-container .login-form[data-v-c62df1a8]{position:relative;width:520px;max-width:100%;padding:160px 35px 0;margin:0 auto;overflow:hidden}.login-container .tips[data-v-c62df1a8]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips span[data-v-c62df1a8]:first-of-type{margin-right:16px}.login-container .svg-container[data-v-c62df1a8]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title-container[data-v-c62df1a8]{position:relative}.login-container .title-container .title[data-v-c62df1a8]{font-size:26px;color:#eee;margin:0 auto 40px auto;text-align:center;font-weight:700}.login-container .show-pwd[data-v-c62df1a8]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.login-container .thirdparty-button[data-v-c62df1a8]{position:absolute;right:0;bottom:6px}@media only screen and (max-width:470px){.login-container .thirdparty-button[data-v-c62df1a8]{display:none}}
|
||||
.social-signup-container[data-v-7309fbbb]{margin:20px 0}.social-signup-container .sign-btn[data-v-7309fbbb]{display:inline-block;cursor:pointer}.social-signup-container .icon[data-v-7309fbbb]{color:#fff;font-size:24px;margin-top:8px}.social-signup-container .qq-svg-container[data-v-7309fbbb],.social-signup-container .wx-svg-container[data-v-7309fbbb]{display:inline-block;width:40px;height:40px;line-height:40px;text-align:center;padding-top:1px;border-radius:4px;margin-bottom:20px;margin-right:5px}.social-signup-container .wx-svg-container[data-v-7309fbbb]{background-color:#24da70}.social-signup-container .qq-svg-container[data-v-7309fbbb]{background-color:#6ba2d6;margin-left:50px}@supports(-webkit-mask:none) and (not (cater-color:#fff)){.login-container .el-input input{color:#fff}}.login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#fff;height:47px;caret-color:#fff}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #283443 inset!important;box-shadow:inset 0 0 0 1000px #283443!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container[data-v-4349c150]{min-height:100%;width:100%;background-color:#2d3a4b;overflow:hidden}.login-container .login-form[data-v-4349c150]{position:relative;width:520px;max-width:100%;padding:160px 35px 0;margin:0 auto;overflow:hidden}.login-container .tips[data-v-4349c150]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips span[data-v-4349c150]:first-of-type{margin-right:16px}.login-container .svg-container[data-v-4349c150]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title-container[data-v-4349c150]{position:relative}.login-container .title-container .title[data-v-4349c150]{font-size:26px;color:#eee;margin:0 auto 40px auto;text-align:center;font-weight:700}.login-container .show-pwd[data-v-4349c150]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.login-container .thirdparty-button[data-v-4349c150]{position:absolute;right:0;bottom:6px}@media only screen and (max-width:470px){.login-container .thirdparty-button[data-v-4349c150]{display:none}}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-5911c282"],{"1db4":function(t,s,a){"use strict";a.r(s);var e=function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"wscn-http404-container"},[a("div",{staticClass:"wscn-http404"},[t._m(0),t._v(" "),a("div",{staticClass:"bullshit"},[a("div",{staticClass:"bullshit__oops"},[t._v("OOPS!")]),t._v(" "),t._m(1),t._v(" "),a("div",{staticClass:"bullshit__headline"},[t._v(t._s(t.message))]),t._v(" "),a("div",{staticClass:"bullshit__info"},[t._v("Please check that the URL you entered is correct, or click the button below to return to the homepage.")]),t._v(" "),a("a",{staticClass:"bullshit__return-home",attrs:{href:""}},[t._v("Back to home")])])])])},c=[function(){var t=this,s=t.$createElement,e=t._self._c||s;return e("div",{staticClass:"pic-404"},[e("img",{staticClass:"pic-404__parent",attrs:{src:a("a36b"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child left",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child mid",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child right",attrs:{src:a("26fc"),alt:"404"}})])},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"bullshit__info"},[t._v("All rights reserved\n "),a("a",{staticStyle:{color:"#20a0ff"},attrs:{href:"https://wallstreetcn.com",target:"_blank"}},[t._v("wallstreetcn")])])}],i={name:"Page404",computed:{message:function(){return"The webmaster said that you can not enter this page..."}}},l=i,n=(a("89a2"),a("2877")),r=Object(n["a"])(l,e,c,!1,null,"26fcd89f",null);s["default"]=r.exports},"26fc":function(t,s,a){t.exports=a.p+"static/img/404_cloud.0f4bc32b.png"},"89a2":function(t,s,a){"use strict";a("bd40")},a36b:function(t,s,a){t.exports=a.p+"static/img/404.a57b6f31.png"},bd40:function(t,s,a){}}]);
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-06c697fe"],{"1db4":function(t,s,a){"use strict";a.r(s);var e=function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"wscn-http404-container"},[a("div",{staticClass:"wscn-http404"},[t._m(0),t._v(" "),a("div",{staticClass:"bullshit"},[a("div",{staticClass:"bullshit__oops"},[t._v("OOPS!")]),t._v(" "),t._m(1),t._v(" "),a("div",{staticClass:"bullshit__headline"},[t._v(t._s(t.message))]),t._v(" "),a("div",{staticClass:"bullshit__info"},[t._v("Please check that the URL you entered is correct, or click the button below to return to the homepage.")]),t._v(" "),a("a",{staticClass:"bullshit__return-home",attrs:{href:""}},[t._v("Back to home")])])])])},c=[function(){var t=this,s=t.$createElement,e=t._self._c||s;return e("div",{staticClass:"pic-404"},[e("img",{staticClass:"pic-404__parent",attrs:{src:a("a36b"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child left",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child mid",attrs:{src:a("26fc"),alt:"404"}}),t._v(" "),e("img",{staticClass:"pic-404__child right",attrs:{src:a("26fc"),alt:"404"}})])},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"bullshit__info"},[t._v("All rights reserved\n "),a("a",{staticStyle:{color:"#20a0ff"},attrs:{href:"https://wallstreetcn.com",target:"_blank"}},[t._v("wallstreetcn")])])}],i={name:"Page404",computed:{message:function(){return"The webmaster said that you can not enter this page..."}}},l=i,n=(a("207f"),a("2877")),r=Object(n["a"])(l,e,c,!1,null,"26fcd89f",null);s["default"]=r.exports},"207f":function(t,s,a){"use strict";a("6632")},"26fc":function(t,s,a){t.exports=a.p+"static/img/404_cloud.0f4bc32b.png"},6632:function(t,s,a){},a36b:function(t,s,a){t.exports=a.p+"static/img/404.a57b6f31.png"}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d230a36"],{ecac:function(e,t,a){"use strict";a.r(t);var s=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticClass:"app-container"},[e.user?a("div",[a("el-row",{attrs:{gutter:20}},[a("el-col",{attrs:{span:6,xs:24}},[a("user-card",{attrs:{user:e.user}})],1),e._v(" "),a("el-col",{attrs:{span:18,xs:24}},[a("el-card",[a("el-tabs",{model:{value:e.activeTab,callback:function(t){e.activeTab=t},expression:"activeTab"}},[a("el-tab-pane",{attrs:{label:"Account",name:"account"}},[a("account",{attrs:{user:e.user}})],1)],1)],1)],1)],1)],1):e._e()])},n=[],r=a("5530"),l=(a("b0c0"),a("a15b"),a("2f62")),c=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("el-form",[a("el-form-item",{attrs:{label:"Name"}},[a("el-input",{model:{value:e.user.name,callback:function(t){e.$set(e.user,"name","string"===typeof t?t.trim():t)},expression:"user.name"}})],1),e._v(" "),a("el-form-item",{attrs:{label:"Email"}},[a("el-input",{model:{value:e.user.email,callback:function(t){e.$set(e.user,"email","string"===typeof t?t.trim():t)},expression:"user.email"}})],1),e._v(" "),a("el-form-item",[a("el-button",{attrs:{type:"primary"},on:{click:e.submit}},[e._v("Update")])],1)],1)},i=[],u={props:{user:{type:Object,default:function(){return{name:"",email:""}}}},methods:{submit:function(){this.$message({message:"User information has been updated successfully",type:"success",duration:5e3})}}},o=u,m=a("2877"),p=Object(m["a"])(o,c,i,!1,null,null,null),b=p.exports,f={name:"Profile",components:{Account:b},data:function(){return{user:{},activeTab:"activity"}},computed:Object(r["a"])({},Object(l["b"])(["name","avatar","roles"])),created:function(){this.getUser()},methods:{getUser:function(){this.user={name:this.name,role:this.roles.join(" | "),email:"admin@test.com",avatar:this.avatar}}}},d=f,v=Object(m["a"])(d,s,n,!1,null,null,null);t["default"]=v.exports}}]);
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d230a36"],{ecac:function(e,t,a){"use strict";a.r(t);var s=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticClass:"app-container"},[e.user?a("div",[a("el-row",{attrs:{gutter:20}},[a("el-col",{attrs:{span:6,xs:24}},[a("user-card",{attrs:{user:e.user}})],1),e._v(" "),a("el-col",{attrs:{span:18,xs:24}},[a("el-card",[a("el-tabs",{model:{value:e.activeTab,callback:function(t){e.activeTab=t},expression:"activeTab"}},[a("el-tab-pane",{attrs:{label:"Account",name:"account"}},[a("account",{attrs:{user:e.user}})],1)],1)],1)],1)],1)],1):e._e()])},n=[],r=a("5530"),l=(a("a15b"),a("b0c0"),a("2f62")),c=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("el-form",[a("el-form-item",{attrs:{label:"Name"}},[a("el-input",{model:{value:e.user.name,callback:function(t){e.$set(e.user,"name","string"===typeof t?t.trim():t)},expression:"user.name"}})],1),e._v(" "),a("el-form-item",{attrs:{label:"Email"}},[a("el-input",{model:{value:e.user.email,callback:function(t){e.$set(e.user,"email","string"===typeof t?t.trim():t)},expression:"user.email"}})],1),e._v(" "),a("el-form-item",[a("el-button",{attrs:{type:"primary"},on:{click:e.submit}},[e._v("Update")])],1)],1)},i=[],u={props:{user:{type:Object,default:function(){return{name:"",email:""}}}},methods:{submit:function(){this.$message({message:"User information has been updated successfully",type:"success",duration:5e3})}}},o=u,m=a("2877"),p=Object(m["a"])(o,c,i,!1,null,null,null),b=p.exports,f={name:"Profile",components:{Account:b},data:function(){return{user:{},activeTab:"activity"}},computed:Object(r["a"])({},Object(l["b"])(["name","avatar","roles"])),created:function(){this.getUser()},methods:{getUser:function(){this.user={name:this.name,role:this.roles.join(" | "),email:"admin@test.com",avatar:this.avatar}}}},d=f,v=Object(m["a"])(d,s,n,!1,null,null,null);t["default"]=v.exports}}]);
|
||||
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-ef888edc"],{"24e2":function(t,a,i){"use strict";i.r(a);var e=function(){var t=this,a=t.$createElement,i=t._self._c||a;return i("div",{staticClass:"errPage-container"},[i("el-button",{staticClass:"pan-back-btn",attrs:{icon:"arrow-left"},on:{click:t.back}},[t._v("\n 返回\n ")]),t._v(" "),i("el-row",[i("el-col",{attrs:{span:12}},[i("h1",{staticClass:"text-jumbo text-ginormous"},[t._v("\n Oops!\n ")]),t._v("\n gif来源"),i("a",{attrs:{href:"https://zh.airbnb.com/",target:"_blank"}},[t._v("airbnb")]),t._v(" 页面\n "),i("h2",[t._v("你没有权限去该页面")]),t._v(" "),i("h6",[t._v("如有不满请联系你领导")]),t._v(" "),i("ul",{staticClass:"list-unstyled"},[i("li",[t._v("或者你可以去:")]),t._v(" "),i("li",{staticClass:"link-type"},[i("router-link",{attrs:{to:"/dashboard"}},[t._v("\n 回首页\n ")])],1),t._v(" "),i("li",{staticClass:"link-type"},[i("a",{attrs:{href:"https://www.taobao.com/"}},[t._v("随便看看")])]),t._v(" "),i("li",[i("a",{attrs:{href:"#"},on:{click:function(a){a.preventDefault(),t.dialogVisible=!0}}},[t._v("点我看图")])])])]),t._v(" "),i("el-col",{attrs:{span:12}},[i("img",{attrs:{src:t.errGif,width:"313",height:"428",alt:"Girl has dropped her ice cream."}})])],1),t._v(" "),i("el-dialog",{attrs:{visible:t.dialogVisible,title:"随便看"},on:{"update:visible":function(a){t.dialogVisible=a}}},[i("img",{staticClass:"pan-img",attrs:{src:t.ewizardClap}})])],1)},s=[],n=(i("14d9"),i("cc6c")),r=i.n(n),l={name:"Page401",data:function(){return{errGif:r.a+"?"+ +new Date,ewizardClap:"https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646",dialogVisible:!1}},methods:{back:function(){this.$route.query.noGoBack?this.$router.push({path:"/dashboard"}):this.$router.go(-1)}}},c=l,o=(i("6f5a"),i("2877")),u=Object(o["a"])(c,e,s,!1,null,"6fb1594e",null);a["default"]=u.exports},"6f5a":function(t,a,i){"use strict";i("a68a")},a68a:function(t,a,i){},cc6c:function(t,a,i){t.exports=i.p+"static/img/401.089007e7.gif"}}]);
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-36deb5d7"],{"24e2":function(t,a,i){"use strict";i.r(a);var e=function(){var t=this,a=t.$createElement,i=t._self._c||a;return i("div",{staticClass:"errPage-container"},[i("el-button",{staticClass:"pan-back-btn",attrs:{icon:"arrow-left"},on:{click:t.back}},[t._v("\n 返回\n ")]),t._v(" "),i("el-row",[i("el-col",{attrs:{span:12}},[i("h1",{staticClass:"text-jumbo text-ginormous"},[t._v("\n Oops!\n ")]),t._v("\n gif来源"),i("a",{attrs:{href:"https://zh.airbnb.com/",target:"_blank"}},[t._v("airbnb")]),t._v(" 页面\n "),i("h2",[t._v("你没有权限去该页面")]),t._v(" "),i("h6",[t._v("如有不满请联系你领导")]),t._v(" "),i("ul",{staticClass:"list-unstyled"},[i("li",[t._v("或者你可以去:")]),t._v(" "),i("li",{staticClass:"link-type"},[i("router-link",{attrs:{to:"/dashboard"}},[t._v("\n 回首页\n ")])],1),t._v(" "),i("li",{staticClass:"link-type"},[i("a",{attrs:{href:"https://www.taobao.com/"}},[t._v("随便看看")])]),t._v(" "),i("li",[i("a",{attrs:{href:"#"},on:{click:function(a){a.preventDefault(),t.dialogVisible=!0}}},[t._v("点我看图")])])])]),t._v(" "),i("el-col",{attrs:{span:12}},[i("img",{attrs:{src:t.errGif,width:"313",height:"428",alt:"Girl has dropped her ice cream."}})])],1),t._v(" "),i("el-dialog",{attrs:{visible:t.dialogVisible,title:"随便看"},on:{"update:visible":function(a){t.dialogVisible=a}}},[i("img",{staticClass:"pan-img",attrs:{src:t.ewizardClap}})])],1)},s=[],n=(i("14d9"),i("cc6c")),r=i.n(n),l={name:"Page401",data:function(){return{errGif:r.a+"?"+ +new Date,ewizardClap:"https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646",dialogVisible:!1}},methods:{back:function(){this.$route.query.noGoBack?this.$router.push({path:"/dashboard"}):this.$router.go(-1)}}},c=l,o=(i("748d"),i("2877")),u=Object(o["a"])(c,e,s,!1,null,"6fb1594e",null);a["default"]=u.exports},"346a":function(t,a,i){},"748d":function(t,a,i){"use strict";i("346a")},cc6c:function(t,a,i){t.exports=i.p+"static/img/401.089007e7.gif"}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-9472305a"],{"129f":function(n,e){n.exports=Object.is||function(n,e){return n===e?0!==n||1/n===1/e:n!=n&&e!=e}},"841c":function(n,e,t){"use strict";var a=t("c65b"),c=t("d784"),r=t("825a"),o=t("7234"),i=t("1d80"),u=t("129f"),d=t("577e"),l=t("dc4a"),s=t("14c3");c("search",(function(n,e,t){return[function(e){var t=i(this),c=o(e)?void 0:l(e,n);return c?a(c,e,t):new RegExp(e)[n](d(t))},function(n){var a=r(this),c=d(n),o=t(e,a,c);if(o.done)return o.value;var i=a.lastIndex;u(i,0)||(a.lastIndex=0);var l=s(a,c);return u(a.lastIndex,i)||(a.lastIndex=i),null===l?-1:l.index}]}))},b829:function(n,e,t){"use strict";t.r(e);t("fb6a"),t("ac1f"),t("841c");var a,c,r={name:"AuthRedirect",created:function(){var n=window.location.search.slice(1);window.localStorage&&(window.localStorage.setItem("x-admin-oauth-code",n),window.close())},render:function(n){return n()}},o=r,i=t("2877"),u=Object(i["a"])(o,a,c,!1,null,null,null);e["default"]=u.exports}}]);
|
||||
@ -0,0 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-9472305a"],{"129f":function(n,e,t){"use strict";n.exports=Object.is||function(n,e){return n===e?0!==n||1/n===1/e:n!==n&&e!==e}},"841c":function(n,e,t){"use strict";var c=t("c65b"),r=t("d784"),a=t("825a"),o=t("861d"),i=t("1d80"),u=t("129f"),d=t("577e"),s=t("dc4a"),l=t("14c3");r("search",(function(n,e,t){return[function(e){var t=i(this),r=o(e)?s(e,n):void 0;return r?c(r,e,t):new RegExp(e)[n](d(t))},function(n){var c=a(this),r=d(n),o=t(e,c,r);if(o.done)return o.value;var i=c.lastIndex;u(i,0)||(c.lastIndex=0);var s=l(c,r);return u(c.lastIndex,i)||(c.lastIndex=i),null===s?-1:s.index}]}))},b829:function(n,e,t){"use strict";t.r(e);t("fb6a"),t("ac1f"),t("841c");var c,r,a={name:"AuthRedirect",created:function(){var n=window.location.search.slice(1);window.localStorage&&(window.localStorage.setItem("x-admin-oauth-code",n),window.close())},render:function(n){return n()}},o=a,i=t("2877"),u=Object(i["a"])(o,c,r,!1,null,null,null);e["default"]=u.exports}}]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue