Wenjun Ruan
6 months ago
committed by
GitHub
65 changed files with 1781 additions and 503 deletions
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration scan="true" scanPeriod="120 seconds"> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -1,143 +0,0 @@
|
||||
/* |
||||
* 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 org.apache.dolphinscheduler.plugin.registry.etcd; |
||||
|
||||
import org.apache.dolphinscheduler.registry.api.Event; |
||||
import org.apache.dolphinscheduler.registry.api.SubscribeListener; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
import java.util.concurrent.CountDownLatch; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
import org.junit.jupiter.api.AfterAll; |
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.BeforeAll; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import io.etcd.jetcd.test.EtcdClusterExtension; |
||||
|
||||
public class EtcdRegistryTest { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(EtcdRegistryTest.class); |
||||
|
||||
public static EtcdRegistry registry; |
||||
|
||||
@BeforeAll |
||||
public static void before() throws Exception { |
||||
EtcdClusterExtension server = EtcdClusterExtension.builder() |
||||
.withNodes(1) |
||||
.withImage("ibmcom/etcd:3.2.24") |
||||
.build(); |
||||
EtcdRegistryProperties properties = new EtcdRegistryProperties(); |
||||
server.restart(); |
||||
properties.setEndpoints(String.valueOf(server.clientEndpoints().get(0))); |
||||
registry = new EtcdRegistry(properties); |
||||
registry.put("/sub", "sub", false); |
||||
} |
||||
|
||||
@Test |
||||
public void persistTest() { |
||||
registry.put("/nodes/m1", "", false); |
||||
registry.put("/nodes/m2", "", false); |
||||
Assertions.assertEquals(Arrays.asList("m1", "m2"), registry.children("/nodes")); |
||||
Assertions.assertTrue(registry.exists("/nodes/m1")); |
||||
registry.delete("/nodes/m2"); |
||||
Assertions.assertFalse(registry.exists("/nodes/m2")); |
||||
registry.delete("/nodes"); |
||||
Assertions.assertFalse(registry.exists("/nodes/m1")); |
||||
} |
||||
|
||||
@Test |
||||
public void lockTest() { |
||||
CountDownLatch preCountDownLatch = new CountDownLatch(1); |
||||
CountDownLatch allCountDownLatch = new CountDownLatch(2); |
||||
List<String> testData = new ArrayList<>(); |
||||
new Thread(() -> { |
||||
registry.acquireLock("/lock"); |
||||
preCountDownLatch.countDown(); |
||||
logger.info(Thread.currentThread().getName() |
||||
+ " :I got the lock, but I don't want to work. I want to rest for a while"); |
||||
try { |
||||
Thread.sleep(1000); |
||||
logger.info(Thread.currentThread().getName() + " :I'm going to start working"); |
||||
testData.add("thread1"); |
||||
|
||||
} catch (InterruptedException e) { |
||||
Thread.currentThread().interrupt(); |
||||
} finally { |
||||
logger.info(Thread.currentThread().getName() + " :I have finished my work, now I release the lock"); |
||||
registry.releaseLock("/lock"); |
||||
allCountDownLatch.countDown(); |
||||
} |
||||
}).start(); |
||||
try { |
||||
preCountDownLatch.await(5, TimeUnit.SECONDS); |
||||
} catch (InterruptedException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
new Thread(() -> { |
||||
try { |
||||
logger.info(Thread.currentThread().getName() + " :I am trying to acquire the lock"); |
||||
registry.acquireLock("/lock"); |
||||
logger.info(Thread.currentThread().getName() + " :I got the lock and I started working"); |
||||
|
||||
testData.add("thread2"); |
||||
} finally { |
||||
registry.releaseLock("/lock"); |
||||
allCountDownLatch.countDown(); |
||||
} |
||||
|
||||
}).start(); |
||||
try { |
||||
allCountDownLatch.await(5, TimeUnit.SECONDS); |
||||
} catch (InterruptedException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
Assertions.assertEquals(testData, Arrays.asList("thread1", "thread2")); |
||||
} |
||||
|
||||
@Test |
||||
public void subscribeTest() { |
||||
boolean status = registry.subscribe("/sub", new TestListener()); |
||||
// The following add and delete operations are used for debugging
|
||||
registry.put("/sub/m1", "tt", false); |
||||
registry.put("/sub/m2", "tt", false); |
||||
registry.delete("/sub/m2"); |
||||
registry.delete("/sub"); |
||||
Assertions.assertTrue(status); |
||||
|
||||
} |
||||
|
||||
static class TestListener implements SubscribeListener { |
||||
|
||||
@Override |
||||
public void notify(Event event) { |
||||
logger.info("I'm test listener"); |
||||
} |
||||
} |
||||
|
||||
@AfterAll |
||||
public static void after() throws IOException { |
||||
registry.close(); |
||||
} |
||||
} |
@ -0,0 +1,70 @@
|
||||
/* |
||||
* 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 org.apache.dolphinscheduler.plugin.registry.etcd; |
||||
|
||||
import org.apache.dolphinscheduler.plugin.registry.RegistryTestCase; |
||||
|
||||
import java.net.URI; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import lombok.SneakyThrows; |
||||
|
||||
import org.junit.jupiter.api.AfterAll; |
||||
import org.junit.jupiter.api.BeforeAll; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
|
||||
import io.etcd.jetcd.launcher.EtcdCluster; |
||||
import io.etcd.jetcd.test.EtcdClusterExtension; |
||||
|
||||
@SpringBootTest(classes = EtcdRegistryProperties.class) |
||||
@SpringBootApplication(scanBasePackageClasses = EtcdRegistryProperties.class) |
||||
public class EtcdRegistryTestCase extends RegistryTestCase<EtcdRegistry> { |
||||
|
||||
@Autowired |
||||
private EtcdRegistryProperties etcdRegistryProperties; |
||||
|
||||
private static EtcdCluster etcdCluster; |
||||
|
||||
@SneakyThrows |
||||
@BeforeAll |
||||
public static void setUpTestingServer() { |
||||
etcdCluster = EtcdClusterExtension.builder() |
||||
.withNodes(1) |
||||
.withImage("ibmcom/etcd:3.2.24") |
||||
.build() |
||||
.cluster(); |
||||
etcdCluster.start(); |
||||
System.setProperty("registry.endpoints", |
||||
etcdCluster.clientEndpoints().stream().map(URI::toString).collect(Collectors.joining(","))); |
||||
} |
||||
|
||||
@SneakyThrows |
||||
@Override |
||||
public EtcdRegistry createRegistry() { |
||||
return new EtcdRegistry(etcdRegistryProperties); |
||||
} |
||||
|
||||
@SneakyThrows |
||||
@AfterAll |
||||
public static void tearDownTestingServer() { |
||||
try (EtcdCluster cluster = etcdCluster) { |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
|
||||
# |
||||
# 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. |
||||
# |
||||
|
||||
registry: |
||||
type: etcd |
||||
ttl: 2s |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<parent> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-registry-plugins</artifactId> |
||||
<version>dev-SNAPSHOT</version> |
||||
</parent> |
||||
|
||||
<artifactId>dolphinscheduler-registry-it</artifactId> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.apache.dolphinscheduler</groupId> |
||||
<artifactId>dolphinscheduler-registry-api</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-test</artifactId> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
<build> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>org.apache.maven.plugins</groupId> |
||||
<artifactId>maven-jar-plugin</artifactId> |
||||
<configuration> |
||||
<skip>false</skip> |
||||
</configuration> |
||||
<executions> |
||||
<execution> |
||||
<goals> |
||||
<goal>test-jar</goal> |
||||
</goals> |
||||
</execution> |
||||
</executions> |
||||
</plugin> |
||||
</plugins> |
||||
</build> |
||||
|
||||
</project> |
@ -0,0 +1,290 @@
|
||||
/* |
||||
* 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 org.apache.dolphinscheduler.plugin.registry; |
||||
|
||||
import static org.awaitility.Awaitility.await; |
||||
import static org.junit.jupiter.api.Assertions.assertThrows; |
||||
|
||||
import org.apache.dolphinscheduler.registry.api.ConnectionState; |
||||
import org.apache.dolphinscheduler.registry.api.Event; |
||||
import org.apache.dolphinscheduler.registry.api.Registry; |
||||
import org.apache.dolphinscheduler.registry.api.RegistryException; |
||||
import org.apache.dolphinscheduler.registry.api.SubscribeListener; |
||||
|
||||
import java.time.Duration; |
||||
import java.util.concurrent.CompletableFuture; |
||||
import java.util.concurrent.TimeUnit; |
||||
import java.util.concurrent.TimeoutException; |
||||
import java.util.concurrent.atomic.AtomicBoolean; |
||||
import java.util.concurrent.atomic.AtomicReference; |
||||
|
||||
import lombok.SneakyThrows; |
||||
|
||||
import org.assertj.core.util.Lists; |
||||
import org.junit.jupiter.api.AfterEach; |
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import com.google.common.truth.Truth; |
||||
|
||||
public abstract class RegistryTestCase<R extends Registry> { |
||||
|
||||
protected R registry; |
||||
|
||||
@BeforeEach |
||||
public void setupRegistry() { |
||||
registry = createRegistry(); |
||||
} |
||||
|
||||
@SneakyThrows |
||||
@AfterEach |
||||
public void tearDownRegistry() { |
||||
try (R registry = this.registry) { |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testIsConnected() { |
||||
registry.start(); |
||||
Truth.assertThat(registry.isConnected()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
public void testConnectUntilTimeout() { |
||||
registry.start(); |
||||
await().atMost(Duration.ofSeconds(10)) |
||||
.untilAsserted(() -> registry.connectUntilTimeout(Duration.ofSeconds(3))); |
||||
|
||||
} |
||||
|
||||
@SneakyThrows |
||||
@Test |
||||
public void testSubscribe() { |
||||
registry.start(); |
||||
|
||||
final AtomicBoolean subscribeAdded = new AtomicBoolean(false); |
||||
final AtomicBoolean subscribeRemoved = new AtomicBoolean(false); |
||||
final AtomicBoolean subscribeUpdated = new AtomicBoolean(false); |
||||
|
||||
SubscribeListener subscribeListener = event -> { |
||||
System.out.println("Receive event: " + event); |
||||
if (event.type() == Event.Type.ADD) { |
||||
subscribeAdded.compareAndSet(false, true); |
||||
} |
||||
if (event.type() == Event.Type.REMOVE) { |
||||
subscribeRemoved.compareAndSet(false, true); |
||||
} |
||||
if (event.type() == Event.Type.UPDATE) { |
||||
subscribeUpdated.compareAndSet(false, true); |
||||
} |
||||
}; |
||||
String key = "/nodes/master" + System.nanoTime(); |
||||
registry.subscribe(key, subscribeListener); |
||||
registry.put(key, String.valueOf(System.nanoTime()), true); |
||||
// Sleep 3 seconds here since in mysql jdbc registry
|
||||
// If multiple event occurs in a refresh time, only the last event will be triggered
|
||||
Thread.sleep(3000); |
||||
registry.put(key, String.valueOf(System.nanoTime()), true); |
||||
Thread.sleep(3000); |
||||
registry.delete(key); |
||||
|
||||
await().atMost(Duration.ofSeconds(10)) |
||||
.untilAsserted(() -> { |
||||
Assertions.assertTrue(subscribeAdded.get()); |
||||
Assertions.assertTrue(subscribeUpdated.get()); |
||||
Assertions.assertTrue(subscribeRemoved.get()); |
||||
}); |
||||
} |
||||
|
||||
@SneakyThrows |
||||
@Test |
||||
public void testUnsubscribe() { |
||||
registry.start(); |
||||
|
||||
final AtomicBoolean subscribeAdded = new AtomicBoolean(false); |
||||
final AtomicBoolean subscribeRemoved = new AtomicBoolean(false); |
||||
final AtomicBoolean subscribeUpdated = new AtomicBoolean(false); |
||||
|
||||
SubscribeListener subscribeListener = event -> { |
||||
if (event.type() == Event.Type.ADD) { |
||||
subscribeAdded.compareAndSet(false, true); |
||||
} |
||||
if (event.type() == Event.Type.REMOVE) { |
||||
subscribeRemoved.compareAndSet(false, true); |
||||
} |
||||
if (event.type() == Event.Type.UPDATE) { |
||||
subscribeUpdated.compareAndSet(false, true); |
||||
} |
||||
}; |
||||
String key = "/nodes/master" + System.nanoTime(); |
||||
String value = "127.0.0.1:8080"; |
||||
registry.subscribe(key, subscribeListener); |
||||
registry.unsubscribe(key); |
||||
registry.put(key, value, true); |
||||
registry.put(key, value, true); |
||||
registry.delete(key); |
||||
|
||||
Thread.sleep(2000); |
||||
Assertions.assertFalse(subscribeAdded.get()); |
||||
Assertions.assertFalse(subscribeRemoved.get()); |
||||
Assertions.assertFalse(subscribeUpdated.get()); |
||||
|
||||
} |
||||
|
||||
@SneakyThrows |
||||
@Test |
||||
public void testAddConnectionStateListener() { |
||||
|
||||
AtomicReference<ConnectionState> connectionState = new AtomicReference<>(); |
||||
registry.addConnectionStateListener(connectionState::set); |
||||
|
||||
Truth.assertThat(connectionState.get()).isNull(); |
||||
registry.start(); |
||||
|
||||
await().atMost(Duration.ofSeconds(2)) |
||||
.until(() -> ConnectionState.CONNECTED == connectionState.get()); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testGet() { |
||||
registry.start(); |
||||
String key = "/nodes/master" + System.nanoTime(); |
||||
String value = "127.0.0.1:8080"; |
||||
assertThrows(RegistryException.class, () -> registry.get(key)); |
||||
registry.put(key, value, true); |
||||
Truth.assertThat(registry.get(key)).isEqualTo(value); |
||||
} |
||||
|
||||
@Test |
||||
public void testPut() { |
||||
registry.start(); |
||||
String key = "/nodes/master" + System.nanoTime(); |
||||
String value = "127.0.0.1:8080"; |
||||
registry.put(key, value, true); |
||||
Truth.assertThat(registry.get(key)).isEqualTo(value); |
||||
|
||||
// Update the value
|
||||
registry.put(key, "123", true); |
||||
Truth.assertThat(registry.get(key)).isEqualTo("123"); |
||||
} |
||||
|
||||
@Test |
||||
public void testDelete() { |
||||
registry.start(); |
||||
String key = "/nodes/master" + System.nanoTime(); |
||||
String value = "127.0.0.1:8080"; |
||||
// Delete a non-existent key
|
||||
registry.delete(key); |
||||
|
||||
registry.put(key, value, true); |
||||
Truth.assertThat(registry.get(key)).isEqualTo(value); |
||||
registry.delete(key); |
||||
Truth.assertThat(registry.exists(key)).isFalse(); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void testChildren() { |
||||
registry.start(); |
||||
String master1 = "/nodes/children/127.0.0.1:8080"; |
||||
String master2 = "/nodes/children/127.0.0.2:8080"; |
||||
String value = "123"; |
||||
registry.put(master1, value, true); |
||||
registry.put(master2, value, true); |
||||
Truth.assertThat(registry.children("/nodes/children")) |
||||
.containsAtLeastElementsIn(Lists.newArrayList("127.0.0.1:8080", "127.0.0.2:8080")); |
||||
} |
||||
|
||||
@Test |
||||
public void testExists() { |
||||
registry.start(); |
||||
String key = "/nodes/master" + System.nanoTime(); |
||||
String value = "123"; |
||||
Truth.assertThat(registry.exists(key)).isFalse(); |
||||
registry.put(key, value, true); |
||||
Truth.assertThat(registry.exists(key)).isTrue(); |
||||
|
||||
} |
||||
|
||||
@SneakyThrows |
||||
@Test |
||||
public void testAcquireLock() { |
||||
registry.start(); |
||||
String lockKey = "/lock" + System.nanoTime(); |
||||
|
||||
// 1. Acquire the lock at the main thread
|
||||
Truth.assertThat(registry.acquireLock(lockKey)).isTrue(); |
||||
// Acquire the lock at the main thread again
|
||||
// It should acquire success
|
||||
Truth.assertThat(registry.acquireLock(lockKey)).isTrue(); |
||||
|
||||
// Acquire the lock at another thread
|
||||
// It should acquire failed
|
||||
CompletableFuture<Boolean> acquireResult = CompletableFuture.supplyAsync(() -> registry.acquireLock(lockKey)); |
||||
assertThrows(TimeoutException.class, () -> acquireResult.get(3000, TimeUnit.MILLISECONDS)); |
||||
|
||||
} |
||||
|
||||
@SneakyThrows |
||||
@Test |
||||
public void testAcquireLock_withTimeout() { |
||||
registry.start(); |
||||
String lockKey = "/lock" + System.nanoTime(); |
||||
// 1. Acquire the lock in the main thread
|
||||
Truth.assertThat(registry.acquireLock(lockKey, 3000)).isTrue(); |
||||
|
||||
// Acquire the lock in the main thread
|
||||
// It should acquire success
|
||||
Truth.assertThat(registry.acquireLock(lockKey, 3000)).isTrue(); |
||||
|
||||
// Acquire the lock at another thread
|
||||
// It should acquire failed
|
||||
CompletableFuture<Boolean> acquireResult = |
||||
CompletableFuture.supplyAsync(() -> registry.acquireLock(lockKey, 3000)); |
||||
Truth.assertThat(acquireResult.get()).isFalse(); |
||||
|
||||
} |
||||
|
||||
@SneakyThrows |
||||
@Test |
||||
public void testReleaseLock() { |
||||
registry.start(); |
||||
String lockKey = "/lock" + System.nanoTime(); |
||||
// 1. Acquire the lock in the main thread
|
||||
Truth.assertThat(registry.acquireLock(lockKey, 3000)).isTrue(); |
||||
|
||||
// Acquire the lock at another thread
|
||||
// It should acquire failed
|
||||
CompletableFuture<Boolean> acquireResult = |
||||
CompletableFuture.supplyAsync(() -> registry.acquireLock(lockKey, 3000)); |
||||
Truth.assertThat(acquireResult.get()).isFalse(); |
||||
|
||||
// 2. Release the lock in the main thread
|
||||
Truth.assertThat(registry.releaseLock(lockKey)).isTrue(); |
||||
|
||||
// Acquire the lock at another thread
|
||||
// It should acquire success
|
||||
acquireResult = CompletableFuture.supplyAsync(() -> registry.acquireLock(lockKey, 3000)); |
||||
Truth.assertThat(acquireResult.get()).isTrue(); |
||||
} |
||||
|
||||
public abstract R createRegistry(); |
||||
|
||||
} |
10
dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/task/EphemeralDateManager.java → dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/EphemeralDateManager.java
10
dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/task/EphemeralDateManager.java → dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/EphemeralDateManager.java
@ -0,0 +1,34 @@
|
||||
/* |
||||
* 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 org.apache.dolphinscheduler.plugin.registry.jdbc; |
||||
|
||||
import org.apache.dolphinscheduler.common.utils.NetUtils; |
||||
import org.apache.dolphinscheduler.common.utils.OSUtils; |
||||
|
||||
import lombok.experimental.UtilityClass; |
||||
|
||||
@UtilityClass |
||||
public class LockUtils { |
||||
|
||||
private static final String LOCK_OWNER_PREFIX = NetUtils.getHost() + "_" + OSUtils.getProcessID() + "_"; |
||||
|
||||
public static String getLockOwner() { |
||||
return LOCK_OWNER_PREFIX + Thread.currentThread().getName(); |
||||
} |
||||
|
||||
} |
57
dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/task/RegistryLockManager.java → dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/RegistryLockManager.java
57
dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/task/RegistryLockManager.java → dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/RegistryLockManager.java
18
dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/task/SubscribeDataManager.java → dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/SubscribeDataManager.java
18
dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/task/SubscribeDataManager.java → dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/SubscribeDataManager.java
@ -0,0 +1,41 @@
|
||||
/* |
||||
* 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 org.apache.dolphinscheduler.plugin.registry.jdbc; |
||||
|
||||
import org.apache.dolphinscheduler.plugin.registry.RegistryTestCase; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
|
||||
@SpringBootTest(classes = {JdbcRegistryProperties.class}) |
||||
@SpringBootApplication(scanBasePackageClasses = JdbcRegistryProperties.class) |
||||
public abstract class JdbcRegistryTestCase extends RegistryTestCase<JdbcRegistry> { |
||||
|
||||
@Autowired |
||||
private JdbcRegistryProperties jdbcRegistryProperties; |
||||
|
||||
@Autowired |
||||
private JdbcOperator jdbcOperator; |
||||
|
||||
@Override |
||||
public JdbcRegistry createRegistry() { |
||||
return new JdbcRegistry(jdbcRegistryProperties, jdbcOperator); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,103 @@
|
||||
/* |
||||
* 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 org.apache.dolphinscheduler.plugin.registry.jdbc; |
||||
|
||||
import java.sql.Connection; |
||||
import java.sql.DriverManager; |
||||
import java.sql.Statement; |
||||
import java.util.stream.Stream; |
||||
|
||||
import lombok.SneakyThrows; |
||||
|
||||
import org.junit.jupiter.api.AfterAll; |
||||
import org.junit.jupiter.api.BeforeAll; |
||||
import org.springframework.test.context.ActiveProfiles; |
||||
import org.testcontainers.containers.GenericContainer; |
||||
import org.testcontainers.containers.MySQLContainer; |
||||
import org.testcontainers.containers.Network; |
||||
import org.testcontainers.containers.wait.strategy.Wait; |
||||
import org.testcontainers.lifecycle.Startables; |
||||
import org.testcontainers.utility.DockerImageName; |
||||
|
||||
import com.google.common.collect.Lists; |
||||
|
||||
@ActiveProfiles("mysql") |
||||
class MysqlJdbcRegistryTestCase extends JdbcRegistryTestCase { |
||||
|
||||
private static GenericContainer<?> mysqlContainer; |
||||
|
||||
@SneakyThrows |
||||
@BeforeAll |
||||
public static void setUpTestingServer() { |
||||
mysqlContainer = new MySQLContainer(DockerImageName.parse("mysql:8.0")) |
||||
.withUsername("root") |
||||
.withPassword("root") |
||||
.withDatabaseName("dolphinscheduler") |
||||
.withNetwork(Network.newNetwork()) |
||||
.withExposedPorts(3306) |
||||
.waitingFor(Wait.forHealthcheck()); |
||||
|
||||
mysqlContainer.setPortBindings(Lists.newArrayList("3306:3306")); |
||||
Startables.deepStart(Stream.of(mysqlContainer)).join(); |
||||
|
||||
try ( |
||||
Connection connection = DriverManager.getConnection( |
||||
"jdbc:mysql://localhost:3306/dolphinscheduler?useSSL=false&serverTimezone=UTC", "root", "root"); |
||||
Statement statement = connection.createStatement();) { |
||||
statement.execute( |
||||
"CREATE TABLE `t_ds_jdbc_registry_data`\n" + |
||||
"(\n" + |
||||
" `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key',\n" + |
||||
" `data_key` varchar(256) NOT NULL COMMENT 'key, like zookeeper node path',\n" + |
||||
" `data_value` text NOT NULL COMMENT 'data, like zookeeper node value',\n" |
||||
+ |
||||
" `data_type` tinyint(4) NOT NULL COMMENT '1: ephemeral node, 2: persistent node',\n" |
||||
+ |
||||
" `last_term` bigint NOT NULL COMMENT 'last term time',\n" + |
||||
" `last_update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'last update time',\n" |
||||
+ |
||||
" `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create time',\n" |
||||
+ |
||||
" PRIMARY KEY (`id`),\n" + |
||||
" unique (`data_key`)\n" + |
||||
") ENGINE = InnoDB\n" + |
||||
" DEFAULT CHARSET = utf8;"); |
||||
statement.execute( |
||||
"CREATE TABLE `t_ds_jdbc_registry_lock`\n" + |
||||
"(\n" + |
||||
" `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key',\n" + |
||||
" `lock_key` varchar(256) NOT NULL COMMENT 'lock path',\n" + |
||||
" `lock_owner` varchar(256) NOT NULL COMMENT 'the lock owner, ip_processId',\n" + |
||||
" `last_term` bigint NOT NULL COMMENT 'last term time',\n" + |
||||
" `last_update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'last update time',\n" |
||||
+ |
||||
" `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create time',\n" |
||||
+ |
||||
" PRIMARY KEY (`id`),\n" + |
||||
" unique (`lock_key`)\n" + |
||||
") ENGINE = InnoDB\n" + |
||||
" DEFAULT CHARSET = utf8;"); |
||||
} |
||||
} |
||||
|
||||
@SneakyThrows |
||||
@AfterAll |
||||
public static void tearDownTestingServer() { |
||||
mysqlContainer.close(); |
||||
} |
||||
} |
@ -0,0 +1,98 @@
|
||||
/* |
||||
* 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 org.apache.dolphinscheduler.plugin.registry.jdbc; |
||||
|
||||
import java.sql.Connection; |
||||
import java.sql.DriverManager; |
||||
import java.sql.Statement; |
||||
import java.util.stream.Stream; |
||||
|
||||
import lombok.SneakyThrows; |
||||
|
||||
import org.junit.jupiter.api.AfterAll; |
||||
import org.junit.jupiter.api.BeforeAll; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.test.context.ActiveProfiles; |
||||
import org.testcontainers.containers.GenericContainer; |
||||
import org.testcontainers.containers.Network; |
||||
import org.testcontainers.containers.PostgreSQLContainer; |
||||
import org.testcontainers.lifecycle.Startables; |
||||
import org.testcontainers.utility.DockerImageName; |
||||
|
||||
import com.google.common.collect.Lists; |
||||
|
||||
@ActiveProfiles("postgresql") |
||||
@SpringBootTest(classes = {JdbcRegistryProperties.class}) |
||||
@SpringBootApplication(scanBasePackageClasses = JdbcRegistryProperties.class) |
||||
public class PostgresqlJdbcRegistryTestCase extends JdbcRegistryTestCase { |
||||
|
||||
private static GenericContainer<?> postgresqlContainer; |
||||
|
||||
@SneakyThrows |
||||
@BeforeAll |
||||
public static void setUpTestingServer() { |
||||
postgresqlContainer = new PostgreSQLContainer(DockerImageName.parse("postgres:16.0")) |
||||
.withUsername("root") |
||||
.withPassword("root") |
||||
.withDatabaseName("dolphinscheduler") |
||||
.withNetwork(Network.newNetwork()) |
||||
.withExposedPorts(5432); |
||||
postgresqlContainer.setPortBindings(Lists.newArrayList("5432:5432")); |
||||
Startables.deepStart(Stream.of(postgresqlContainer)).join(); |
||||
|
||||
try ( |
||||
Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/dolphinscheduler", |
||||
"root", "root"); |
||||
Statement statement = connection.createStatement();) { |
||||
statement.execute( |
||||
"create table t_ds_jdbc_registry_data\n" + |
||||
"(\n" + |
||||
" id serial\n" + |
||||
" constraint t_ds_jdbc_registry_data_pk primary key,\n" + |
||||
" data_key varchar not null,\n" + |
||||
" data_value text not null,\n" + |
||||
" data_type int4 not null,\n" + |
||||
" last_term bigint not null,\n" + |
||||
" last_update_time timestamp default current_timestamp not null,\n" + |
||||
" create_time timestamp default current_timestamp not null\n" + |
||||
");"); |
||||
statement.execute( |
||||
"create unique index t_ds_jdbc_registry_data_key_uindex on t_ds_jdbc_registry_data (data_key);"); |
||||
statement.execute( |
||||
"create table t_ds_jdbc_registry_lock\n" + |
||||
"(\n" + |
||||
" id serial\n" + |
||||
" constraint t_ds_jdbc_registry_lock_pk primary key,\n" + |
||||
" lock_key varchar not null,\n" + |
||||
" lock_owner varchar not null,\n" + |
||||
" last_term bigint not null,\n" + |
||||
" last_update_time timestamp default current_timestamp not null,\n" + |
||||
" create_time timestamp default current_timestamp not null\n" + |
||||
");"); |
||||
statement.execute( |
||||
"create unique index t_ds_jdbc_registry_lock_key_uindex on t_ds_jdbc_registry_lock (lock_key);"); |
||||
} |
||||
} |
||||
|
||||
@SneakyThrows |
||||
@AfterAll |
||||
public static void tearDownTestingServer() { |
||||
postgresqlContainer.close(); |
||||
} |
||||
} |
@ -0,0 +1,31 @@
|
||||
# |
||||
# 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. |
||||
# |
||||
spring: |
||||
sql: |
||||
init: |
||||
schema-locations: classpath:mysql_registry_init.sql |
||||
datasource: |
||||
driver-class-name: com.mysql.cj.jdbc.Driver |
||||
url: jdbc:mysql://localhost:3306/dolphinscheduler?useUnicode=true&characterEncoding=UTF-8 |
||||
username: root |
||||
password: root |
||||
|
||||
registry: |
||||
type: jdbc |
||||
term-refresh-interval: 1s |
||||
term-expire-times: 1 |
||||
|
@ -0,0 +1,28 @@
|
||||
# |
||||
# 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. |
||||
# |
||||
spring: |
||||
datasource: |
||||
driver-class-name: org.postgresql.Driver |
||||
url: jdbc:postgresql://localhost:5432/dolphinscheduler |
||||
username: root |
||||
password: root |
||||
|
||||
registry: |
||||
type: jdbc |
||||
term-refresh-interval: 1s |
||||
term-expire-times: 1 |
||||
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -1,131 +0,0 @@
|
||||
/* |
||||
* 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 org.apache.dolphinscheduler.plugin.registry.zookeeper; |
||||
|
||||
import org.apache.dolphinscheduler.registry.api.Event; |
||||
import org.apache.dolphinscheduler.registry.api.SubscribeListener; |
||||
|
||||
import org.apache.curator.test.TestingServer; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
import java.util.concurrent.CountDownLatch; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
import org.junit.jupiter.api.AfterEach; |
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
public class ZookeeperRegistryTest { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ZookeeperRegistryTest.class); |
||||
|
||||
TestingServer server; |
||||
|
||||
ZookeeperRegistry registry; |
||||
|
||||
@BeforeEach |
||||
public void before() throws Exception { |
||||
server = new TestingServer(true); |
||||
|
||||
ZookeeperRegistryProperties p = new ZookeeperRegistryProperties(); |
||||
p.getZookeeper().setConnectString(server.getConnectString()); |
||||
registry = new ZookeeperRegistry(p); |
||||
registry.start(); |
||||
registry.put("/sub", "", false); |
||||
} |
||||
|
||||
@Test |
||||
public void persistTest() { |
||||
registry.put("/nodes/m1", "", false); |
||||
registry.put("/nodes/m2", "", false); |
||||
Assertions.assertEquals(Arrays.asList("m2", "m1"), registry.children("/nodes")); |
||||
Assertions.assertTrue(registry.exists("/nodes/m1")); |
||||
registry.delete("/nodes/m2"); |
||||
Assertions.assertFalse(registry.exists("/nodes/m2")); |
||||
} |
||||
|
||||
@Test |
||||
public void lockTest() throws InterruptedException { |
||||
CountDownLatch preCountDownLatch = new CountDownLatch(1); |
||||
CountDownLatch allCountDownLatch = new CountDownLatch(2); |
||||
List<String> testData = new ArrayList<>(); |
||||
new Thread(() -> { |
||||
registry.acquireLock("/lock"); |
||||
preCountDownLatch.countDown(); |
||||
logger.info(Thread.currentThread().getName() |
||||
+ " :I got the lock, but I don't want to work. I want to rest for a while"); |
||||
try { |
||||
Thread.sleep(1000); |
||||
logger.info(Thread.currentThread().getName() + " :I'm going to start working"); |
||||
testData.add("thread1"); |
||||
|
||||
} catch (InterruptedException e) { |
||||
Thread.currentThread().interrupt(); |
||||
} finally { |
||||
logger.info(Thread.currentThread().getName() + " :I have finished my work, now I release the lock"); |
||||
registry.releaseLock("/lock"); |
||||
allCountDownLatch.countDown(); |
||||
} |
||||
}).start(); |
||||
preCountDownLatch.await(5, TimeUnit.SECONDS); |
||||
new Thread(() -> { |
||||
try { |
||||
logger.info(Thread.currentThread().getName() + " :I am trying to acquire the lock"); |
||||
registry.acquireLock("/lock"); |
||||
logger.info(Thread.currentThread().getName() + " :I got the lock and I started working"); |
||||
|
||||
testData.add("thread2"); |
||||
} finally { |
||||
registry.releaseLock("/lock"); |
||||
allCountDownLatch.countDown(); |
||||
} |
||||
|
||||
}).start(); |
||||
allCountDownLatch.await(5, TimeUnit.SECONDS); |
||||
Assertions.assertEquals(testData, Arrays.asList("thread1", "thread2")); |
||||
|
||||
} |
||||
|
||||
@Test |
||||
public void subscribeTest() { |
||||
boolean status = registry.subscribe("/sub", new TestListener()); |
||||
Assertions.assertTrue(status); |
||||
|
||||
} |
||||
|
||||
static class TestListener implements SubscribeListener { |
||||
|
||||
@Override |
||||
public void notify(Event event) { |
||||
logger.info("I'm test listener"); |
||||
} |
||||
} |
||||
|
||||
@AfterEach |
||||
public void after() throws IOException { |
||||
registry.close(); |
||||
server.close(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,71 @@
|
||||
/* |
||||
* 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 org.apache.dolphinscheduler.plugin.registry.zookeeper; |
||||
|
||||
import org.apache.dolphinscheduler.plugin.registry.RegistryTestCase; |
||||
|
||||
import java.util.stream.Stream; |
||||
|
||||
import lombok.SneakyThrows; |
||||
|
||||
import org.junit.jupiter.api.AfterAll; |
||||
import org.junit.jupiter.api.BeforeAll; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.testcontainers.containers.GenericContainer; |
||||
import org.testcontainers.containers.Network; |
||||
import org.testcontainers.lifecycle.Startables; |
||||
import org.testcontainers.utility.DockerImageName; |
||||
|
||||
import com.google.common.collect.Lists; |
||||
|
||||
@SpringBootTest(classes = ZookeeperRegistryProperties.class) |
||||
@SpringBootApplication(scanBasePackageClasses = ZookeeperRegistryProperties.class) |
||||
class ZookeeperRegistryTestCase extends RegistryTestCase<ZookeeperRegistry> { |
||||
|
||||
@Autowired |
||||
private ZookeeperRegistryProperties zookeeperRegistryProperties; |
||||
|
||||
private static GenericContainer<?> zookeeperContainer; |
||||
|
||||
private static final Network NETWORK = Network.newNetwork(); |
||||
|
||||
@SneakyThrows |
||||
@BeforeAll |
||||
public static void setUpTestingServer() { |
||||
zookeeperContainer = new GenericContainer<>(DockerImageName.parse("zookeeper:3.8")) |
||||
.withNetwork(NETWORK); |
||||
|
||||
zookeeperContainer.setPortBindings(Lists.newArrayList("2181:2181")); |
||||
Startables.deepStart(Stream.of(zookeeperContainer)).join(); |
||||
System.setProperty("registry.zookeeper.connect-string", "localhost:2181"); |
||||
} |
||||
|
||||
@SneakyThrows |
||||
@Override |
||||
public ZookeeperRegistry createRegistry() { |
||||
return new ZookeeperRegistry(zookeeperRegistryProperties); |
||||
} |
||||
|
||||
@SneakyThrows |
||||
@AfterAll |
||||
public static void tearDownTestingServer() { |
||||
zookeeperContainer.close(); |
||||
} |
||||
} |
@ -0,0 +1,30 @@
|
||||
# |
||||
# 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. |
||||
# |
||||
|
||||
registry: |
||||
type: zookeeper |
||||
zookeeper: |
||||
namespace: dolphinscheduler |
||||
connect-string: 127.0.0.1:2181 |
||||
retry-policy: |
||||
base-sleep-time: 60ms |
||||
max-sleep: 300ms |
||||
max-retries: 5 |
||||
session-timeout: 30s |
||||
connection-timeout: 9s |
||||
block-until-connected: 600ms |
||||
digest: ~ |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
~ 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. |
||||
--> |
||||
|
||||
<configuration> |
||||
<logger name="*" level="ERROR"/> |
||||
</configuration> |
Loading…
Reference in new issue