42 changed files with 852 additions and 412 deletions
@ -1,85 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* Licensed 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.thingsboard.server.utils; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.util.concurrent.Executor; |
|||
import java.util.concurrent.ExecutorService; |
|||
import java.util.function.Consumer; |
|||
|
|||
/** |
|||
* This class deduplicate executions of the specified function. |
|||
* Useful in cluster mode, when you get event about partition change multiple times. |
|||
* Assuming that the function execution is expensive, we should execute it immediately when first time event occurs and |
|||
* later, once the processing of first event is done, process last pending task. |
|||
* |
|||
* @param <P> parameters of the function |
|||
*/ |
|||
@Slf4j |
|||
public class EventDeduplicationExecutor<P> { |
|||
private final String name; |
|||
private final ExecutorService executor; |
|||
private final Consumer<P> function; |
|||
private P pendingTask; |
|||
private boolean busy; |
|||
|
|||
public EventDeduplicationExecutor(String name, ExecutorService executor, Consumer<P> function) { |
|||
this.name = name; |
|||
this.executor = executor; |
|||
this.function = function; |
|||
} |
|||
|
|||
public void submit(P params) { |
|||
log.info("[{}] Going to submit: {}", name, params); |
|||
synchronized (EventDeduplicationExecutor.this) { |
|||
if (!busy) { |
|||
busy = true; |
|||
pendingTask = null; |
|||
try { |
|||
log.info("[{}] Submitting task: {}", name, params); |
|||
executor.submit(() -> { |
|||
try { |
|||
log.info("[{}] Executing task: {}", name, params); |
|||
function.accept(params); |
|||
} catch (Throwable e) { |
|||
log.warn("[{}] Failed to process task with parameters: {}", name, params, e); |
|||
throw e; |
|||
} finally { |
|||
unlockAndProcessIfAny(); |
|||
} |
|||
}); |
|||
} catch (Throwable e) { |
|||
log.warn("[{}] Failed to submit task with parameters: {}", name, params, e); |
|||
unlockAndProcessIfAny(); |
|||
throw e; |
|||
} |
|||
} else { |
|||
log.info("[{}] Task is already in progress. {} pending task: {}", name, pendingTask == null ? "adding" : "updating", params); |
|||
pendingTask = params; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void unlockAndProcessIfAny() { |
|||
synchronized (EventDeduplicationExecutor.this) { |
|||
busy = false; |
|||
if (pendingTask != null) { |
|||
submit(pendingTask); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,58 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* Licensed 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.thingsboard.server.service.mail; |
|||
|
|||
import org.mockito.Mockito; |
|||
import org.mockito.invocation.InvocationOnMock; |
|||
import org.mockito.stubbing.Answer; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.context.annotation.Primary; |
|||
import org.springframework.context.annotation.Profile; |
|||
import org.thingsboard.rule.engine.api.MailService; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
|
|||
@Profile("test") |
|||
@Configuration |
|||
public class TestMailService { |
|||
|
|||
public static String currentActivateToken; |
|||
public static String currentResetPasswordToken; |
|||
|
|||
@Bean |
|||
@Primary |
|||
public MailService mailService() throws ThingsboardException { |
|||
MailService mailService = Mockito.mock(MailService.class); |
|||
Mockito.doAnswer(new Answer<Void>() { |
|||
public Void answer(InvocationOnMock invocation) { |
|||
Object[] args = invocation.getArguments(); |
|||
String activationLink = (String) args[0]; |
|||
currentActivateToken = activationLink.split("=")[1]; |
|||
return null; |
|||
} |
|||
}).when(mailService).sendActivationEmail(Mockito.anyString(), Mockito.anyString()); |
|||
Mockito.doAnswer(new Answer<Void>() { |
|||
public Void answer(InvocationOnMock invocation) { |
|||
Object[] args = invocation.getArguments(); |
|||
String passwordResetLink = (String) args[0]; |
|||
currentResetPasswordToken = passwordResetLink.split("=")[1]; |
|||
return null; |
|||
} |
|||
}).when(mailService).sendResetPasswordEmailAsync(Mockito.anyString(), Mockito.anyString()); |
|||
return mailService; |
|||
} |
|||
|
|||
} |
|||
@ -1,173 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* Licensed 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.thingsboard.server.util; |
|||
|
|||
import com.google.common.util.concurrent.MoreExecutors; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.junit.After; |
|||
import org.junit.Test; |
|||
import org.junit.runner.RunWith; |
|||
import org.mockito.Mockito; |
|||
import org.mockito.junit.MockitoJUnitRunner; |
|||
import org.thingsboard.common.util.ThingsBoardThreadFactory; |
|||
import org.thingsboard.server.utils.EventDeduplicationExecutor; |
|||
|
|||
import java.util.concurrent.ExecutorService; |
|||
import java.util.concurrent.Executors; |
|||
import java.util.function.Consumer; |
|||
|
|||
@Slf4j |
|||
@RunWith(MockitoJUnitRunner.class) |
|||
public class EventDeduplicationExecutorTest { |
|||
|
|||
ThingsBoardThreadFactory threadFactory = ThingsBoardThreadFactory.forName(getClass().getSimpleName()); |
|||
ExecutorService executor; |
|||
|
|||
@After |
|||
public void tearDown() throws Exception { |
|||
if (executor != null) { |
|||
executor.shutdownNow(); |
|||
} |
|||
} |
|||
|
|||
@Test |
|||
public void testSimpleFlowSameThread() throws InterruptedException { |
|||
simpleFlow(MoreExecutors.newDirectExecutorService()); |
|||
} |
|||
|
|||
@Test |
|||
public void testPeriodicFlowSameThread() throws InterruptedException { |
|||
periodicFlow(MoreExecutors.newDirectExecutorService()); |
|||
} |
|||
|
|||
@Test |
|||
public void testExceptionFlowSameThread() throws InterruptedException { |
|||
exceptionFlow(MoreExecutors.newDirectExecutorService()); |
|||
} |
|||
|
|||
@Test |
|||
public void testSimpleFlowSingleThread() throws InterruptedException { |
|||
executor = Executors.newSingleThreadExecutor(threadFactory); |
|||
simpleFlow(executor); |
|||
} |
|||
|
|||
@Test |
|||
public void testPeriodicFlowSingleThread() throws InterruptedException { |
|||
executor = Executors.newSingleThreadExecutor(threadFactory); |
|||
periodicFlow(executor); |
|||
} |
|||
|
|||
@Test |
|||
public void testExceptionFlowSingleThread() throws InterruptedException { |
|||
executor = Executors.newSingleThreadExecutor(threadFactory); |
|||
exceptionFlow(executor); |
|||
} |
|||
|
|||
@Test |
|||
public void testSimpleFlowMultiThread() throws InterruptedException { |
|||
executor = Executors.newFixedThreadPool(3, threadFactory); |
|||
simpleFlow(executor); |
|||
} |
|||
|
|||
@Test |
|||
public void testPeriodicFlowMultiThread() throws InterruptedException { |
|||
executor = Executors.newFixedThreadPool(3, threadFactory); |
|||
periodicFlow(executor); |
|||
} |
|||
|
|||
@Test |
|||
public void testExceptionFlowMultiThread() throws InterruptedException { |
|||
executor = Executors.newFixedThreadPool(3, threadFactory); |
|||
exceptionFlow(executor); |
|||
} |
|||
|
|||
private void simpleFlow(ExecutorService executorService) throws InterruptedException { |
|||
try { |
|||
Consumer<String> function = Mockito.spy(StringConsumer.class); |
|||
EventDeduplicationExecutor<String> executor = new EventDeduplicationExecutor<>(EventDeduplicationExecutorTest.class.getSimpleName(), executorService, function); |
|||
|
|||
String params1 = "params1"; |
|||
String params2 = "params2"; |
|||
String params3 = "params3"; |
|||
|
|||
executor.submit(params1); |
|||
executor.submit(params2); |
|||
executor.submit(params3); |
|||
Thread.sleep(500); |
|||
Mockito.verify(function).accept(params1); |
|||
Mockito.verify(function).accept(params3); |
|||
} finally { |
|||
executorService.shutdownNow(); |
|||
} |
|||
} |
|||
|
|||
private void periodicFlow(ExecutorService executorService) throws InterruptedException { |
|||
try { |
|||
Consumer<String> function = Mockito.spy(StringConsumer.class); |
|||
EventDeduplicationExecutor<String> executor = new EventDeduplicationExecutor<>(EventDeduplicationExecutorTest.class.getSimpleName(), executorService, function); |
|||
|
|||
String params1 = "params1"; |
|||
String params2 = "params2"; |
|||
String params3 = "params3"; |
|||
|
|||
executor.submit(params1); |
|||
Thread.sleep(500); |
|||
executor.submit(params2); |
|||
Thread.sleep(500); |
|||
executor.submit(params3); |
|||
Thread.sleep(500); |
|||
Mockito.verify(function).accept(params1); |
|||
Mockito.verify(function).accept(params2); |
|||
Mockito.verify(function).accept(params3); |
|||
} finally { |
|||
executorService.shutdownNow(); |
|||
} |
|||
} |
|||
|
|||
private void exceptionFlow(ExecutorService executorService) throws InterruptedException { |
|||
try { |
|||
Consumer<String> function = Mockito.spy(StringConsumer.class); |
|||
EventDeduplicationExecutor<String> executor = new EventDeduplicationExecutor<>(EventDeduplicationExecutorTest.class.getSimpleName(), executorService, function); |
|||
|
|||
String params1 = "params1"; |
|||
String params2 = "params2"; |
|||
String params3 = "params3"; |
|||
|
|||
Mockito.doThrow(new RuntimeException()).when(function).accept("params1"); |
|||
executor.submit(params1); |
|||
executor.submit(params2); |
|||
Thread.sleep(500); |
|||
executor.submit(params3); |
|||
Thread.sleep(500); |
|||
Mockito.verify(function).accept(params2); |
|||
Mockito.verify(function).accept(params3); |
|||
} finally { |
|||
executorService.shutdownNow(); |
|||
} |
|||
} |
|||
|
|||
public static class StringConsumer implements Consumer<String> { |
|||
@Override |
|||
public void accept(String s) { |
|||
try { |
|||
Thread.sleep(100); |
|||
} catch (InterruptedException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
# |
|||
# Copyright © 2016-2023 The Thingsboard Authors |
|||
# |
|||
# Licensed 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. |
|||
# |
|||
|
|||
version: '3.0' |
|||
|
|||
services: |
|||
cassandra: |
|||
environment: |
|||
HEAP_NEWSIZE: 128M |
|||
MAX_HEAP_SIZE: 1024M |
|||
@ -0,0 +1,19 @@ |
|||
# |
|||
# Copyright © 2016-2023 The Thingsboard Authors |
|||
# |
|||
# Licensed 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. |
|||
# |
|||
|
|||
version: '3.0' |
|||
|
|||
# Placeholder |
|||
@ -0,0 +1,73 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* Licensed 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.thingsboard.rule.engine.credentials; |
|||
|
|||
import org.apache.commons.io.FileUtils; |
|||
import org.junit.Assert; |
|||
import org.junit.Test; |
|||
|
|||
import java.io.File; |
|||
import java.io.IOException; |
|||
import java.security.cert.X509Certificate; |
|||
import java.util.List; |
|||
|
|||
public class CertPemCredentialsTest { |
|||
|
|||
private final CertPemCredentials credentials = new CertPemCredentials(); |
|||
|
|||
@Test |
|||
public void testChainOfCertificates() throws Exception { |
|||
String fileContent = fileContent("pem/tb-cloud-chain.pem"); |
|||
|
|||
List<X509Certificate> x509Certificates = credentials.readCertFile(fileContent); |
|||
|
|||
Assert.assertEquals(4, x509Certificates.size()); |
|||
Assert.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US", |
|||
x509Certificates.get(0).getSubjectDN().getName()); |
|||
Assert.assertEquals("CN=Sectigo ECC Organization Validation Secure Server CA, O=Sectigo Limited, L=Salford, ST=Greater Manchester, C=GB", |
|||
x509Certificates.get(1).getSubjectDN().getName()); |
|||
Assert.assertEquals("CN=USERTrust ECC Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US", |
|||
x509Certificates.get(2).getSubjectDN().getName()); |
|||
Assert.assertEquals("CN=AAA Certificate Services, O=Comodo CA Limited, L=Salford, ST=Greater Manchester, C=GB", |
|||
x509Certificates.get(3).getSubjectDN().getName()); |
|||
} |
|||
|
|||
@Test |
|||
public void testSingleCertificate() throws Exception { |
|||
String fileContent = fileContent("pem/tb-cloud.pem"); |
|||
|
|||
List<X509Certificate> x509Certificates = credentials.readCertFile(fileContent); |
|||
|
|||
Assert.assertEquals(1, x509Certificates.size()); |
|||
Assert.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US", |
|||
x509Certificates.get(0).getSubjectDN().getName()); |
|||
} |
|||
|
|||
@Test |
|||
public void testEmptyFileContent() throws Exception { |
|||
String fileContent = fileContent("pem/empty.pem"); |
|||
|
|||
List<X509Certificate> x509Certificates = credentials.readCertFile(fileContent); |
|||
|
|||
Assert.assertEquals(0, x509Certificates.size()); |
|||
} |
|||
|
|||
private String fileContent(String fileName) throws IOException { |
|||
ClassLoader classLoader = getClass().getClassLoader(); |
|||
File file = new File(classLoader.getResource(fileName).getFile()); |
|||
return FileUtils.readFileToString(file, "UTF-8"); |
|||
} |
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
-----BEGIN CERTIFICATE----- |
|||
MIIFejCCBSCgAwIBAgIQT2YV5NVp2PAY1O5rxMlj6DAKBggqhkjOPQQDAjCBlTEL |
|||
MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE |
|||
BxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMT0wOwYDVQQDEzRT |
|||
ZWN0aWdvIEVDQyBPcmdhbml6YXRpb24gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVy |
|||
IENBMB4XDTIxMTAwNTAwMDAwMFoXDTIyMTAwNTIzNTk1OVowWjELMAkGA1UEBhMC |
|||
VVMxETAPBgNVBAgTCE5ldyBZb3JrMRowGAYDVQQKExFUaGluZ3NCb2FyZCwgSW5j |
|||
LjEcMBoGA1UEAwwTKi50aGluZ3Nib2FyZC5jbG91ZDB2MBAGByqGSM49AgEGBSuB |
|||
BAAiA2IABNkK/UerQZXPP0H/Tl8YhRPlzW85yTAcQ5hXhs2fyXn7Bdj4EueQuZrv |
|||
Pw98xwHJr87jslFbS/WiSdtBYPvjsUyXqh7aMvOcEhSgEOWDmtoj3P1Xk1hNLb6m |
|||
xAQfFL8cZ6OCA20wggNpMB8GA1UdIwQYMBaAFE1K78RGsxKtT06asVniUasIEHgI |
|||
MB0GA1UdDgQWBBRr4HG23dsao68r9r7obGxB70ptBzAOBgNVHQ8BAf8EBAMCB4Aw |
|||
DAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwSgYD |
|||
VR0gBEMwQTA1BgwrBgEEAbIxAQIBAwQwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9z |
|||
ZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQICMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6 |
|||
Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb0VDQ09yZ2FuaXphdGlvblZhbGlkYXRp |
|||
b25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYoGCCsGAQUFBwEBBH4wfDBVBggrBgEFBQcw |
|||
AoZJaHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvRUNDT3JnYW5pemF0aW9u |
|||
VmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEFBQcwAYYXaHR0cDov |
|||
L29jc3Auc2VjdGlnby5jb20wMQYDVR0RBCowKIITKi50aGluZ3Nib2FyZC5jbG91 |
|||
ZIIRdGhpbmdzYm9hcmQuY2xvdWQwggGABgorBgEEAdZ5AgQCBIIBcASCAWwBagB2 |
|||
AEalVet1+pEgMLWiiWn0830RLEF0vv1JuIWr8vxw/m1HAAABfFDbhtMAAAQDAEcw |
|||
RQIhAKNykhkQTngK0yOcYHGHUQSy6JmJYl+5nc1qELirPHwAAiBgV2Db5ZFHNvzn |
|||
zp9Ob/OG0o36z6rcilbLI/daZwnyewB3AEHIyrHfIkZKEMahOglCh15OMYsbA+vr |
|||
S8do8JBilgb2AAABfFDbhqYAAAQDAEgwRgIhALFvTbapKhO7DPrF6KtE9sjFMMth |
|||
qjqaeaHYN6JGnUAIAiEApEW+rxlzxH1+qEwJrFyQLr5rSKTuEoSjv3hbrzb9GQ4A |
|||
dwApeb7wnjk5IfBWc59jpXflvld9nGAK+PlNXSZcJV3HhAAAAXxQ24ZnAAAEAwBI |
|||
MEYCIQDReSpJPzADl/fBdCvyZwWu3Ubi6y0h/S4i7RIjf5L5pAIhAJ1oUmNmRWQL |
|||
1U3HAqz2V8ckH/rgA0BR+CkGBigt3dfwMAoGCCqGSM49BAMCA0gAMEUCID0Wv3hJ |
|||
GyO4kxlCsA/Kruzew8Wr/0k84csyaCo0k16kAiEAtAobCIzx/PIDWU2rX5elBNiR |
|||
13sr0/ED+2PUom2dnfg= |
|||
-----END CERTIFICATE----- |
|||
-----BEGIN CERTIFICATE----- |
|||
MIIDrjCCAzOgAwIBAgIQNb50Y4yz6d4oBXC3l4CzZzAKBggqhkjOPQQDAzCBiDEL |
|||
MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl |
|||
eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT |
|||
JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgxMTAy |
|||
MDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBlTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT |
|||
EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMP |
|||
U2VjdGlnbyBMaW1pdGVkMT0wOwYDVQQDEzRTZWN0aWdvIEVDQyBPcmdhbml6YXRp |
|||
b24gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMFkwEwYHKoZIzj0CAQYIKoZI |
|||
zj0DAQcDQgAEnI5cCmFvoVij0NXO+vxE+f+6Bh57FhpyH0LTCrJmzfsPSXIhTSex |
|||
r92HOlz+aHqoGE0vSe/CSwLFoWcZ8W1jOaOCAW4wggFqMB8GA1UdIwQYMBaAFDrh |
|||
CYbUzxnClnZ0SXbc4DXGY2OaMB0GA1UdDgQWBBRNSu/ERrMSrU9OmrFZ4lGrCBB4 |
|||
CDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAU |
|||
BggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgGBmeBDAEC |
|||
AjBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVNF |
|||
UlRydXN0RUNDQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdgYIKwYBBQUHAQEE |
|||
ajBoMD8GCCsGAQUFBzAChjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vVVNFUlRy |
|||
dXN0RUNDQWRkVHJ1c3RDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVz |
|||
ZXJ0cnVzdC5jb20wCgYIKoZIzj0EAwMDaQAwZgIxAOk//uo7i/MoeKdcyeqvjOXs |
|||
BJFGLI+1i0d+Tty7zEnn2w4DNS21TK8wmY3Kjm3EmQIxAPI1qHM/I+OS+hx0OZhG |
|||
fDoNifTe/GxgWZ1gOYQKzn6lwP0yGKlrP+7vrVC8IczJ4A== |
|||
-----END CERTIFICATE----- |
|||
-----BEGIN CERTIFICATE----- |
|||
MIID0zCCArugAwIBAgIQVmcdBOpPmUxvEIFHWdJ1lDANBgkqhkiG9w0BAQwFADB7 |
|||
MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD |
|||
VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE |
|||
AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4 |
|||
MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5 |
|||
MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO |
|||
ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0 |
|||
aG9yaXR5MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEGqxUWqn5aCPnetUkb1PGWthL |
|||
q8bVttHmc3Gu3ZzWDGH926CJA7gFFOxXzu5dP+Ihs8731Ip54KODfi2X0GHE8Znc |
|||
JZFjq38wo7Rw4sehM5zzvy5cU7Ffs30yf4o043l5o4HyMIHvMB8GA1UdIwQYMBaA |
|||
FKARCiM+lvEH7OKvKe+CpX/QMKS0MB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1 |
|||
xmNjmjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zARBgNVHSAECjAI |
|||
MAYGBFUdIAAwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5j |
|||
b20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEEKDAmMCQG |
|||
CCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQEM |
|||
BQADggEBABns652JLCALBIAdGN5CmXKZFjK9Dpx1WywV4ilAbe7/ctvbq5AfjJXy |
|||
ij0IckKJUAfiORVsAYfZFhr1wHUrxeZWEQff2Ji8fJ8ZOd+LygBkc7xGEJuTI42+ |
|||
FsMuCIKchjN0djsoTI0DQoWz4rIjQtUfenVqGtF8qmchxDM6OW1TyaLtYiKou+JV |
|||
bJlsQ2uRl9EMC5MCHdK8aXdJ5htN978UeAOwproLtOGFfy/cQjutdAFI3tZs4RmY |
|||
CV4Ks2dH/hzg1cEo70qLRDEmBDeNiXQ2Lu+lIg+DdEmSx/cQwgwp+7e9un/jX9Wf |
|||
8qn0dNW44bOwgeThpWOjzOoEeJBuv/c= |
|||
-----END CERTIFICATE----- |
|||
-----BEGIN CERTIFICATE----- |
|||
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb |
|||
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow |
|||
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj |
|||
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL |
|||
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE |
|||
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM |
|||
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP |
|||
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua |
|||
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe |
|||
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 |
|||
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR |
|||
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm |
|||
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU |
|||
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF |
|||
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v |
|||
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t |
|||
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF |
|||
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q |
|||
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz |
|||
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 |
|||
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi |
|||
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 |
|||
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== |
|||
-----END CERTIFICATE----- |
|||
|
|||
@ -0,0 +1,32 @@ |
|||
-----BEGIN CERTIFICATE----- |
|||
MIIFejCCBSCgAwIBAgIQT2YV5NVp2PAY1O5rxMlj6DAKBggqhkjOPQQDAjCBlTEL |
|||
MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE |
|||
BxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMT0wOwYDVQQDEzRT |
|||
ZWN0aWdvIEVDQyBPcmdhbml6YXRpb24gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVy |
|||
IENBMB4XDTIxMTAwNTAwMDAwMFoXDTIyMTAwNTIzNTk1OVowWjELMAkGA1UEBhMC |
|||
VVMxETAPBgNVBAgTCE5ldyBZb3JrMRowGAYDVQQKExFUaGluZ3NCb2FyZCwgSW5j |
|||
LjEcMBoGA1UEAwwTKi50aGluZ3Nib2FyZC5jbG91ZDB2MBAGByqGSM49AgEGBSuB |
|||
BAAiA2IABNkK/UerQZXPP0H/Tl8YhRPlzW85yTAcQ5hXhs2fyXn7Bdj4EueQuZrv |
|||
Pw98xwHJr87jslFbS/WiSdtBYPvjsUyXqh7aMvOcEhSgEOWDmtoj3P1Xk1hNLb6m |
|||
xAQfFL8cZ6OCA20wggNpMB8GA1UdIwQYMBaAFE1K78RGsxKtT06asVniUasIEHgI |
|||
MB0GA1UdDgQWBBRr4HG23dsao68r9r7obGxB70ptBzAOBgNVHQ8BAf8EBAMCB4Aw |
|||
DAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwSgYD |
|||
VR0gBEMwQTA1BgwrBgEEAbIxAQIBAwQwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9z |
|||
ZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQICMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6 |
|||
Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb0VDQ09yZ2FuaXphdGlvblZhbGlkYXRp |
|||
b25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYoGCCsGAQUFBwEBBH4wfDBVBggrBgEFBQcw |
|||
AoZJaHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvRUNDT3JnYW5pemF0aW9u |
|||
VmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEFBQcwAYYXaHR0cDov |
|||
L29jc3Auc2VjdGlnby5jb20wMQYDVR0RBCowKIITKi50aGluZ3Nib2FyZC5jbG91 |
|||
ZIIRdGhpbmdzYm9hcmQuY2xvdWQwggGABgorBgEEAdZ5AgQCBIIBcASCAWwBagB2 |
|||
AEalVet1+pEgMLWiiWn0830RLEF0vv1JuIWr8vxw/m1HAAABfFDbhtMAAAQDAEcw |
|||
RQIhAKNykhkQTngK0yOcYHGHUQSy6JmJYl+5nc1qELirPHwAAiBgV2Db5ZFHNvzn |
|||
zp9Ob/OG0o36z6rcilbLI/daZwnyewB3AEHIyrHfIkZKEMahOglCh15OMYsbA+vr |
|||
S8do8JBilgb2AAABfFDbhqYAAAQDAEgwRgIhALFvTbapKhO7DPrF6KtE9sjFMMth |
|||
qjqaeaHYN6JGnUAIAiEApEW+rxlzxH1+qEwJrFyQLr5rSKTuEoSjv3hbrzb9GQ4A |
|||
dwApeb7wnjk5IfBWc59jpXflvld9nGAK+PlNXSZcJV3HhAAAAXxQ24ZnAAAEAwBI |
|||
MEYCIQDReSpJPzADl/fBdCvyZwWu3Ubi6y0h/S4i7RIjf5L5pAIhAJ1oUmNmRWQL |
|||
1U3HAqz2V8ckH/rgA0BR+CkGBigt3dfwMAoGCCqGSM49BAMCA0gAMEUCID0Wv3hJ |
|||
GyO4kxlCsA/Kruzew8Wr/0k84csyaCo0k16kAiEAtAobCIzx/PIDWU2rX5elBNiR |
|||
13sr0/ED+2PUom2dnfg= |
|||
-----END CERTIFICATE----- |
|||
Loading…
Reference in new issue