/**
* Copyright 2015 StreamSets Inc.
*
* Licensed under 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 com.streamsets.datacollector.restapi;
import com.google.common.collect.ImmutableList;
import com.streamsets.datacollector.config.PipelineConfiguration;
import com.streamsets.datacollector.creation.RuleDefinitionsConfigBean;
import com.streamsets.datacollector.execution.Manager;
import com.streamsets.datacollector.execution.PipelineState;
import com.streamsets.datacollector.execution.PipelineStatus;
import com.streamsets.datacollector.execution.manager.PipelineStateImpl;
import com.streamsets.datacollector.main.RuntimeInfo;
import com.streamsets.datacollector.main.UserGroupManager;
import com.streamsets.datacollector.restapi.bean.BeanHelper;
import com.streamsets.datacollector.restapi.bean.ConfigConfigurationJson;
import com.streamsets.datacollector.restapi.bean.DataRuleDefinitionJson;
import com.streamsets.datacollector.restapi.bean.DriftRuleDefinitionJson;
import com.streamsets.datacollector.restapi.bean.MetricElementJson;
import com.streamsets.datacollector.restapi.bean.MetricTypeJson;
import com.streamsets.datacollector.restapi.bean.MetricsRuleDefinitionJson;
import com.streamsets.datacollector.restapi.bean.MultiStatusResponseJson;
import com.streamsets.datacollector.restapi.bean.PipelineConfigurationJson;
import com.streamsets.datacollector.restapi.bean.PipelineEnvelopeJson;
import com.streamsets.datacollector.restapi.bean.PipelineInfoJson;
import com.streamsets.datacollector.restapi.bean.PipelineRevInfoJson;
import com.streamsets.datacollector.restapi.bean.PipelineStateJson;
import com.streamsets.datacollector.restapi.bean.RuleDefinitionsJson;
import com.streamsets.datacollector.restapi.bean.StageConfigurationJson;
import com.streamsets.datacollector.restapi.bean.ThresholdTypeJson;
import com.streamsets.datacollector.runner.MockStages;
import com.streamsets.datacollector.stagelibrary.StageLibraryTask;
import com.streamsets.datacollector.store.AclStoreTask;
import com.streamsets.datacollector.store.PipelineInfo;
import com.streamsets.datacollector.store.PipelineStoreException;
import com.streamsets.datacollector.store.PipelineStoreTask;
import com.streamsets.datacollector.store.impl.FileAclStoreTask;
import com.streamsets.datacollector.util.ContainerError;
import com.streamsets.datacollector.util.LockCache;
import com.streamsets.datacollector.util.PipelineException;
import com.streamsets.datacollector.validation.RuleIssue;
import com.streamsets.datacollector.validation.ValidationError;
import com.streamsets.lib.security.acl.dto.Acl;
import com.streamsets.lib.security.acl.dto.Action;
import com.streamsets.lib.security.acl.dto.Permission;
import com.streamsets.lib.security.acl.dto.ResourceType;
import com.streamsets.lib.security.acl.dto.SubjectType;
import com.streamsets.pipeline.api.ExecutionMode;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Singleton;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class TestPipelineStoreResource extends JerseyTest {
private static Logger LOG = LoggerFactory.getLogger(TestPipelineStoreResource.class);
@BeforeClass
public static void beforeClass() {
}
@Test
public void testGetPipelinesCount() {
// when ACL is disabled
isACLEnabled = false;
Response response = target("/v1/pipelines/count").request().get();
Map<String, Object> countRes = (Map<String, Object>)response.readEntity(Map.class);
Assert.assertNotNull(countRes);
Assert.assertEquals(7, countRes.get("count"));
// when ACL is enabled
isACLEnabled = true;
response = target("/v1/pipelines/count").request().get();
countRes = (Map<String, Object>)response.readEntity(Map.class);
Assert.assertNotNull(countRes);
Assert.assertEquals(6, countRes.get("count"));
}
@Test
public void testGetSystemPipelineLabels() {
Response response = target("/v1/pipelines/systemLabels").request().get();
List systemPipelineLabels = response.readEntity(List.class);
Assert.assertNotNull(systemPipelineLabels);
Assert.assertTrue(systemPipelineLabels.size() > 1);
}
@Test
public void testGetPipelineLabels() {
Response response = target("/v1/pipelines/labels").request().get();
List systemPipelineLabels = response.readEntity(List.class);
Assert.assertNotNull(systemPipelineLabels);
Assert.assertTrue(systemPipelineLabels.size() == 1);
Assert.assertEquals("label1", systemPipelineLabels.get(0));
}
@Test
public void testGetPipelines() {
// when ACL is disabled
isACLEnabled = false;
Response response = target("/v1/pipelines").request().get();
List<PipelineInfoJson> pipelineInfoJsons = response.readEntity(new GenericType<List<PipelineInfoJson>>() {});
Assert.assertNotNull(pipelineInfoJsons);
Assert.assertEquals(7, pipelineInfoJsons.size());
// when ACL is enabled
isACLEnabled = true;
response = target("/v1/pipelines").request().get();
pipelineInfoJsons = response.readEntity(new GenericType<List<PipelineInfoJson>>() {});
Assert.assertNotNull(pipelineInfoJsons);
Assert.assertEquals(6, pipelineInfoJsons.size());
}
@Test
public void testGetPipelinesFilteringByText() {
Response response = target("/v1/pipelines")
.queryParam("filterText", "name1")
.request()
.get();
List<PipelineInfoJson> pipelineInfoJsons = response.readEntity(new GenericType<List<PipelineInfoJson>>() {});
Assert.assertNotNull(pipelineInfoJsons);
Assert.assertEquals(1, pipelineInfoJsons.size());
}
@Test
public void testGetPipelinesFilteringByLabel() {
Response response = target("/v1/pipelines")
.queryParam("label", "label1")
.request()
.get();
List<PipelineInfoJson> pipelineInfoJsons = response.readEntity(new GenericType<List<PipelineInfoJson>>() {});
Assert.assertNotNull(pipelineInfoJsons);
Assert.assertEquals(2, pipelineInfoJsons.size());
}
@Test
public void testGetPipelinesSorting() {
Response response = target("/v1/pipelines")
.queryParam("orderBy", "NAME")
.queryParam("order", "ASC")
.request()
.get();
List<PipelineInfoJson> pipelineInfoJsons = response.readEntity(new GenericType<List<PipelineInfoJson>>() {});
Assert.assertNotNull(pipelineInfoJsons);
Assert.assertEquals(6, pipelineInfoJsons.size());
Assert.assertEquals("name1", pipelineInfoJsons.get(0).getPipelineId());
Assert.assertEquals("name2", pipelineInfoJsons.get(1).getPipelineId());
Assert.assertEquals("name3", pipelineInfoJsons.get(2).getPipelineId());
response = target("/v1/pipelines")
.queryParam("orderBy", "NAME")
.queryParam("order", "DESC")
.request()
.get();
pipelineInfoJsons = response.readEntity(new GenericType<List<PipelineInfoJson>>() {});
Assert.assertNotNull(pipelineInfoJsons);
Assert.assertEquals(6, pipelineInfoJsons.size());
Assert.assertEquals("readWriteOnly", pipelineInfoJsons.get(0).getPipelineId());
Assert.assertEquals("readWriteExecute", pipelineInfoJsons.get(1).getPipelineId());
Assert.assertEquals("readOnly", pipelineInfoJsons.get(2).getPipelineId());
response = target("/v1/pipelines")
.queryParam("orderBy", "STATUS")
.queryParam("order", "ASC")
.request()
.get();
pipelineInfoJsons = response.readEntity(new GenericType<List<PipelineInfoJson>>() {});
Assert.assertNotNull(pipelineInfoJsons);
Assert.assertEquals(6, pipelineInfoJsons.size());
Assert.assertEquals("name2", pipelineInfoJsons.get(0).getPipelineId());
Assert.assertEquals("name1", pipelineInfoJsons.get(1).getPipelineId());
Assert.assertEquals("name3", pipelineInfoJsons.get(2).getPipelineId());
}
@Test
public void testGetPipelinesPagination() {
Response response = target("/v1/pipelines")
.queryParam("offset", "1")
.queryParam("len", "2")
.queryParam("orderBy", "NAME")
.queryParam("order", "ASC")
.request()
.get();
List<PipelineInfoJson> pipelineInfoJsons = response.readEntity(new GenericType<List<PipelineInfoJson>>() {});
Assert.assertNotNull(pipelineInfoJsons);
Assert.assertEquals(2, pipelineInfoJsons.size());
Assert.assertEquals("name2", pipelineInfoJsons.get(0).getPipelineId());
Assert.assertEquals("name3", pipelineInfoJsons.get(1).getPipelineId());
Assert.assertNotNull(response.getHeaders().get("TOTAL_COUNT"));
Assert.assertEquals("6", response.getHeaders().get("TOTAL_COUNT").get(0));
}
@Test
public void testGetPipelinesWithStatus() {
Response response = target("/v1/pipelines")
.queryParam("includeStatus", true)
.request()
.get();
List responseObj = response.readEntity(new GenericType<List>() {});
Assert.assertNotNull(responseObj);
Assert.assertEquals(2, responseObj.size());
Assert.assertNotNull(responseObj.get(0));
List<PipelineInfoJson> pipelineInfoJsons = (List<PipelineInfoJson>) responseObj.get(0);
Assert.assertNotNull(pipelineInfoJsons);
Assert.assertEquals(6, pipelineInfoJsons.size());
Assert.assertNotNull(responseObj.get(1));
List<PipelineStateJson> pipelineStateJsons = (List<PipelineStateJson>) responseObj.get(1);
Assert.assertNotNull(pipelineStateJsons);
Assert.assertEquals(3, pipelineStateJsons.size());
}
@Test
public void testGetInfoPipeline() {
Response response = target("/v1/pipeline/xyz").queryParam("rev", "1").queryParam("get", "pipeline").
request().get();
PipelineConfigurationJson pipelineConfig = response.readEntity(PipelineConfigurationJson.class);
Assert.assertNotNull(pipelineConfig);
// test get Info on pipeline for which user doesn't have read permission
boolean exceptionTriggered = false;
try {
response = target("/v1/pipeline/noPerm")
.queryParam("get", "pipeline")
.request()
.get();
} catch (Exception ex) {
exceptionTriggered = true;
Assert.assertTrue(ex.getCause().getMessage().contains("CONTAINER_01200"));
}
Assert.assertTrue(exceptionTriggered);
}
@Test
public void testGetInfoInfo() {
Response response = target("/v1/pipeline/xyz").queryParam("rev", "1.0.0").queryParam("get", "info").
request().get();
PipelineInfoJson pipelineInfoJson = response.readEntity(PipelineInfoJson.class);
Assert.assertNotNull(pipelineInfoJson);
}
@Test
public void testGetInfoHistory() {
Response response = target("/v1/pipeline/xyz").queryParam("rev", "1.0.0").queryParam("get", "history").
request().get();
List<PipelineRevInfoJson> pipelineRevInfoJson = response.readEntity(new GenericType<List<PipelineRevInfoJson>>() {});
Assert.assertNotNull(pipelineRevInfoJson);
// test get Info on pipeline for which user doesn't have read permission
boolean exceptionTriggered = false;
try {
response = target("/v1/pipeline/noPerm")
.queryParam("get", "history")
.request()
.get();
} catch (Exception ex) {
exceptionTriggered = true;
Assert.assertTrue(ex.getCause().getMessage().contains("CONTAINER_01200"));
}
Assert.assertTrue(exceptionTriggered);
}
@Test
public void testCreate() {
Response response = target("/v1/pipeline/myPipeline").queryParam("description", "my description").request()
.put(Entity.json("abc"));
PipelineConfigurationJson pipelineConfig = response.readEntity(PipelineConfigurationJson.class);
Assert.assertEquals(201, response.getStatusInfo().getStatusCode());
Assert.assertNotNull(pipelineConfig);
Assert.assertNotNull(pipelineConfig.getUuid());
Assert.assertEquals(3, pipelineConfig.getStages().size());
StageConfigurationJson stageConf = pipelineConfig.getStages().get(0);
Assert.assertEquals("s", stageConf.getInstanceName());
Assert.assertEquals("sourceName", stageConf.getStageName());
Assert.assertEquals("1", stageConf.getStageVersion());
Assert.assertEquals("default", stageConf.getLibrary());
}
@Test
public void testDelete() {
Response response = target("/v1/pipeline/myPipeline").request().delete();
Assert.assertEquals(200, response.getStatus());
// test delete on pipeline for which user doesn't have write permission
boolean exceptionTriggered = false;
try {
response = target("/v1/pipeline/noPerm")
.request()
.delete();
} catch (Exception ex) {
exceptionTriggered = true;
Assert.assertTrue(ex.getCause().getMessage().contains("CONTAINER_01200"));
}
Assert.assertTrue(exceptionTriggered);
exceptionTriggered = false;
try {
response = target("/v1/pipeline/readOnly")
.request()
.delete();
} catch (Exception ex) {
exceptionTriggered = true;
Assert.assertTrue(ex.getCause().getMessage().contains("CONTAINER_01200"));
}
Assert.assertTrue(exceptionTriggered);
}
@Test
public void testDeleteMultiplePipelines() {
Response response = target("/v1/pipelines/delete").request()
.post(Entity.json("[\"myPipeline1\", \"myPipeline2\"]"));
Assert.assertEquals(200, response.getStatus());
}
@Test
public void testSave() {
PipelineConfiguration toSave = MockStages.createPipelineConfigurationSourceProcessorTarget();
Response response = target("/v1/pipeline/myPipeline")
.queryParam("tag", "tag")
.queryParam("tagDescription", "tagDescription").request()
.post(Entity.json(BeanHelper.wrapPipelineConfiguration(toSave)));
PipelineConfigurationJson returned = response.readEntity(PipelineConfigurationJson.class);
Assert.assertNotNull(returned);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals(toSave.getDescription(), returned.getDescription());
//Assert.assertEquals("A", returned.getMetadata().get("a"));
// test save on pipeline for which user doesn't have write permission
boolean exceptionTriggered = false;
try {
response = target("/v1/pipeline/readOnly")
.queryParam("tag", "tag")
.queryParam("tagDescription", "tagDescription").request()
.post(Entity.json(BeanHelper.wrapPipelineConfiguration(toSave)));
} catch (Exception ex) {
exceptionTriggered = true;
Assert.assertTrue(ex.getCause().getMessage().contains("CONTAINER_01200"));
}
Assert.assertTrue(exceptionTriggered);
// test save on pipeline created by other user and with write permission
response = target("/v1/pipeline/readWriteOnly")
.queryParam("tag", "tag")
.queryParam("tagDescription", "tagDescription").request()
.post(Entity.json(BeanHelper.wrapPipelineConfiguration(toSave)));
returned = response.readEntity(PipelineConfigurationJson.class);
Assert.assertNotNull(returned);
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals(toSave.getDescription(), returned.getDescription());
}
@Test
public void testSaveRules() {
long timestamp = System.currentTimeMillis();
List<MetricsRuleDefinitionJson> metricsRuleDefinitionJsons = new ArrayList<>();
metricsRuleDefinitionJsons.add(new MetricsRuleDefinitionJson("m1", "m1", "a", MetricTypeJson.COUNTER,
MetricElementJson.COUNTER_COUNT, "p", false, true, timestamp));
metricsRuleDefinitionJsons.add(new MetricsRuleDefinitionJson("m2", "m2", "a", MetricTypeJson.TIMER,
MetricElementJson.TIMER_M15_RATE, "p", false, true, timestamp));
metricsRuleDefinitionJsons.add(new MetricsRuleDefinitionJson("m3", "m3", "a", MetricTypeJson.HISTOGRAM,
MetricElementJson.HISTOGRAM_MEAN, "p", false, true, timestamp));
List<DataRuleDefinitionJson> dataRuleDefinitionJsons = new ArrayList<>();
dataRuleDefinitionJsons.add(new DataRuleDefinitionJson("a", "a", "a", 20, 300, "x", true, "a", ThresholdTypeJson.COUNT, "200",
1000, true, false, true, timestamp));
dataRuleDefinitionJsons.add(new DataRuleDefinitionJson("b", "b", "b", 20, 300, "x", true, "a", ThresholdTypeJson.COUNT, "200",
1000, true, false, true, timestamp));
dataRuleDefinitionJsons.add(new DataRuleDefinitionJson("c", "c", "c", 20, 300, "x", true, "a", ThresholdTypeJson.COUNT, "200",
1000, true, false, true, timestamp));
RuleDefinitionsJson ruleDefinitionsJson = new RuleDefinitionsJson(
PipelineStoreTask.RULE_DEFINITIONS_SCHEMA_VERSION,
RuleDefinitionsConfigBean.VERSION,
metricsRuleDefinitionJsons,
dataRuleDefinitionJsons,
Collections.<DriftRuleDefinitionJson>emptyList(),
Collections.<String>emptyList(),
UUID.randomUUID(),
Collections.EMPTY_LIST
);
Response r = target("/v1/pipeline/myPipeline/rules").queryParam("rev", "tag").request()
.post(Entity.json(ruleDefinitionsJson));
RuleDefinitionsJson result = r.readEntity(RuleDefinitionsJson.class);
Assert.assertEquals(3, result.getMetricsRuleDefinitions().size());
Assert.assertEquals(3, result.getDataRuleDefinitions().size());
// test save on pipeline rules for which user doesn't have write permission
boolean exceptionTriggered = false;
try {
r = target("/v1/pipeline/readOnly/rules")
.queryParam("rev", "tag").request()
.post(Entity.json(ruleDefinitionsJson));
} catch (Exception ex) {
exceptionTriggered = true;
Assert.assertTrue(ex.getCause().getMessage().contains("CONTAINER_01200"));
}
Assert.assertTrue(exceptionTriggered);
}
@Test
public void testGetRules() {
Response r = target("/v1/pipeline/myPipeline/rules").queryParam("rev", "tag")
.request().get();
Assert.assertNotNull(r);
RuleDefinitionsJson result = r.readEntity(RuleDefinitionsJson.class);
Assert.assertEquals(3, result.getMetricsRuleDefinitions().size());
Assert.assertEquals(3, result.getDataRuleDefinitions().size());
// test get pipeline rules for which user doesn't have read permission
boolean exceptionTriggered = false;
try {
r = target("/v1/pipeline/noPerm/rules")
.queryParam("rev", "tag")
.request().get();
} catch (Exception ex) {
exceptionTriggered = true;
Assert.assertTrue(ex.getCause().getMessage().contains("CONTAINER_01200"));
}
Assert.assertTrue(exceptionTriggered);
}
@Override
protected Application configure() {
return new ResourceConfig() {
{
register(new PipelineStoreResourceConfig());
register(PipelineStoreResource.class);
}
};
}
static class PipelineStoreResourceConfig extends AbstractBinder {
@Override
protected void configure() {
bindFactory(PipelineStoreTestInjector.class).to(PipelineStoreTask.class);
bindFactory(AclStoreTestInjector.class).to(AclStoreTask.class);
bindFactory(TestUtil.StageLibraryTestInjector.class).to(StageLibraryTask.class);
bindFactory(TestUtil.PrincipalTestInjector.class).to(Principal.class);
bindFactory(TestUtil.URITestInjector.class).to(URI.class);
bindFactory(RuntimeInfoTestInjector.class).to(RuntimeInfo.class);
bindFactory(ManagerTestInjector.class).to(Manager.class);
bindFactory(TestUtil.UserGroupManagerTestInjector.class).to(UserGroupManager.class);
}
}
static PipelineStoreTask pipelineStore;
static class PipelineStoreTestInjector implements Factory<PipelineStoreTask> {
public PipelineStoreTestInjector() {
}
@Singleton
@Override
public PipelineStoreTask provide() {
com.streamsets.datacollector.util.TestUtil.captureStagesForProductionRun();
long timestamp = System.currentTimeMillis();
pipelineStore = Mockito.mock(PipelineStoreTask.class);
try {
Map<String, Object> metadata = new HashMap<>();
metadata.put("labels", ImmutableList.of("label1"));
PipelineInfo pipeline1 = new PipelineInfo(
"name1",
"name1",
"description",
new java.util.Date(0),
new java.util.Date(0),
"user1",
"lastModifier",
"1", UUID.randomUUID(),
true,
metadata
);
PipelineInfo pipeline2 = new PipelineInfo(
"name2",
"label",
"description",
new java.util.Date(0),
new java.util.Date(0),
"user1",
"lastModifier",
"1", UUID.randomUUID(),
true,
metadata
);
PipelineInfo pipeline3 = new PipelineInfo(
"name3",
"label",
"description",
new java.util.Date(0),
new java.util.Date(0),
"user1",
"lastModifier",
"1",
UUID.randomUUID(),
true,
null
);
PipelineInfo readOnly = new PipelineInfo(
"readOnly",
"label",
"description",
new java.util.Date(0),
new java.util.Date(0),
"user2",
"lastModifier",
"1",
UUID.randomUUID(),
true,
null
);
PipelineInfo readWriteOnly = new PipelineInfo(
"readWriteOnly",
"label",
"description",
new java.util.Date(0),
new java.util.Date(0),
"user2",
"lastModifier",
"1",
UUID.randomUUID(),
true,
null
);
PipelineInfo readWriteExecute = new PipelineInfo(
"readWriteExecute",
"label",
"description",
new java.util.Date(0),
new java.util.Date(0),
"user2",
"lastModifier",
"1",
UUID.randomUUID(),
true,
null
);
PipelineInfo noPerm = new PipelineInfo(
"noPerm",
"label",
"description",
new java.util.Date(0),
new java.util.Date(0),
"user2",
"lastModifier",
"1",
UUID.randomUUID(),
true,
null
);
Mockito.when(pipelineStore.getPipelines())
.thenReturn(ImmutableList.of(
pipeline1,
pipeline2,
pipeline3,
readOnly,
readWriteOnly,
readWriteExecute,
noPerm
));
Mockito.when(pipelineStore.getInfo(Matchers.matches("xyz|myPipeline|newFromImport"))).thenReturn(
new PipelineInfo(
"xyz",
"label",
"xyz description",
new java.util.Date(0),
new java.util.Date(0),
"xyz creator",
"xyz lastModifier",
"1", UUID.randomUUID(),
true,
null
)
);
Mockito.when(pipelineStore.getInfo("name1")).thenReturn(pipeline1);
Mockito.when(pipelineStore.getInfo("name2")).thenReturn(pipeline2);
Mockito.when(pipelineStore.getInfo("name3")).thenReturn(pipeline3);
Mockito.when(pipelineStore.getInfo("readOnly")).thenReturn(readOnly);
Mockito.when(pipelineStore.getInfo("readWriteOnly")).thenReturn(readWriteOnly);
Mockito.when(pipelineStore.getInfo("readWriteExecute")).thenReturn(readWriteExecute);
Mockito.when(pipelineStore.getInfo("noPerm")).thenReturn(noPerm);
Mockito.when(pipelineStore.getHistory("xyz")).thenReturn(ImmutableList.of(
new com.streamsets.datacollector.store.PipelineRevInfo(new PipelineInfo("xyz","label",
"xyz description", new java.util.Date(0), new java.util.Date(0), "xyz creator",
"xyz lastModifier", "1", UUID.randomUUID(), true, null))));
Mockito.when(pipelineStore.load("xyz", "1")).thenReturn(
MockStages.createPipelineConfigurationSourceProcessorTarget());
Mockito.when(pipelineStore.load(Matchers.matches("abc|def"), Matchers.matches("0"))).thenReturn(
MockStages.createPipelineConfigurationWithLabels(new ArrayList<String>()));
Mockito.when(pipelineStore.create("user1", "myPipeline", "myPipeline", "my description", false)).thenReturn(
MockStages.createPipelineConfigurationSourceProcessorTarget());
Mockito.doNothing().when(pipelineStore).delete("myPipeline");
Mockito.doThrow(new PipelineStoreException(ContainerError.CONTAINER_0200, "xyz"))
.when(pipelineStore).delete("xyz");
Mockito.when(pipelineStore.save(
Matchers.anyString(), Matchers.anyString(), Matchers.anyString(), Matchers.anyString(),
(com.streamsets.datacollector.config.PipelineConfiguration)Matchers.any())).thenReturn(
MockStages.createPipelineConfigurationSourceProcessorTarget());
Mockito.when(pipelineStore.save(
Matchers.anyString(), Matchers.matches("abc|def"), Matchers.matches("0"), Matchers.anyString(),
(com.streamsets.datacollector.config.PipelineConfiguration)Matchers.any())).thenReturn(
MockStages.createPipelineConfigurationWithLabels(Arrays.asList("foo", "bar")));
List<MetricsRuleDefinitionJson> metricsRuleDefinitionJsons = new ArrayList<>();
metricsRuleDefinitionJsons.add(new MetricsRuleDefinitionJson("m1", "m1", "a", MetricTypeJson.COUNTER,
MetricElementJson.COUNTER_COUNT, "p", false, true, timestamp));
metricsRuleDefinitionJsons.add(new MetricsRuleDefinitionJson("m2", "m2", "a", MetricTypeJson.TIMER,
MetricElementJson.TIMER_M15_RATE, "p", false, true, timestamp));
metricsRuleDefinitionJsons.add(new MetricsRuleDefinitionJson("m3", "m3", "a", MetricTypeJson.HISTOGRAM,
MetricElementJson.HISTOGRAM_MEAN, "p", false, true, timestamp));
List<DataRuleDefinitionJson> dataRuleDefinitionJsons = new ArrayList<>();
dataRuleDefinitionJsons.add(new DataRuleDefinitionJson("a", "a", "a", 20, 300, "x", true, "c", ThresholdTypeJson.COUNT, "200",
1000, true, false,true, timestamp));
dataRuleDefinitionJsons.add(new DataRuleDefinitionJson("b", "b", "b", 20, 300, "x", true, "c", ThresholdTypeJson.COUNT, "200",
1000, true, false, true, timestamp));
dataRuleDefinitionJsons.add(new DataRuleDefinitionJson("c", "c", "c", 20, 300, "x", true, "c", ThresholdTypeJson.COUNT, "200",
1000, true, false, true, timestamp));
RuleDefinitionsJson rules = new RuleDefinitionsJson(
PipelineStoreTask.RULE_DEFINITIONS_SCHEMA_VERSION,
RuleDefinitionsConfigBean.VERSION,
metricsRuleDefinitionJsons,
dataRuleDefinitionJsons,
Collections.<DriftRuleDefinitionJson>emptyList(),
Collections.<String>emptyList(),
UUID.randomUUID(),
Collections.<ConfigConfigurationJson>emptyList()
);
List<RuleIssue> ruleIssues = new ArrayList<>();
ruleIssues.add(RuleIssue.createRuleIssue("a", ValidationError.VALIDATION_0000));
ruleIssues.add(RuleIssue.createRuleIssue("b", ValidationError.VALIDATION_0000));
ruleIssues.add(RuleIssue.createRuleIssue("c", ValidationError.VALIDATION_0000));
rules.getRuleDefinitions().setRuleIssues(ruleIssues);
try {
Mockito.when(pipelineStore.retrieveRules("myPipeline", "tag")).thenReturn(rules.getRuleDefinitions());
Mockito.when(pipelineStore.retrieveRules("xyz", "1")).thenReturn(rules.getRuleDefinitions());
Mockito.when(pipelineStore.retrieveRules("newFromImport", "1")).thenReturn(rules.getRuleDefinitions());
} catch (PipelineStoreException e) {
LOG.debug("Ignoring exception", e);
}
try {
Mockito.when(pipelineStore.storeRules(
Matchers.anyString(), Matchers.anyString(), (com.streamsets.datacollector.config.RuleDefinitions) Matchers.any()))
.thenReturn(rules.getRuleDefinitions());
} catch (PipelineStoreException e) {
LOG.debug("Ignoring exception", e);
}
Mockito.when(pipelineStore.create("user1", "newFromImport", "newFromImport",null, false)).thenReturn(
MockStages.createPipelineConfigurationSourceProcessorTarget());
} catch (com.streamsets.datacollector.util.PipelineException e) {
LOG.debug("Ignoring exception", e);
}
return pipelineStore;
}
@Override
public void dispose(PipelineStoreTask pipelineStore) {
}
}
static AclStoreTask aclStore;
static class AclStoreTestInjector implements Factory<AclStoreTask> {
public AclStoreTestInjector() {
}
@Singleton
@Override
public AclStoreTask provide() {
aclStore = new FileAclStoreTask (Mockito.mock(RuntimeInfo.class), pipelineStore, new LockCache<String>()) {
@Override
public Acl saveAcl(String pipelineName, Acl acl) throws PipelineStoreException {
return null;
}
@Override
public Acl getAcl(String pipelineName) throws PipelineException {
Acl user1Acl = createAcl(
"pipelineId",
ResourceType.PIPELINE,
System.currentTimeMillis(),
"user1"
);
Acl readOnlyAcl = createAcl(
"pipelineId",
ResourceType.PIPELINE,
System.currentTimeMillis(),
"user2"
);
readOnlyAcl.getPermissions().add(
new Permission(
"user1",
SubjectType.USER,
"user2",
System.currentTimeMillis(),
ImmutableList.of(Action.READ)
)
);
Acl readWriteOnlyAcl = createAcl(
"pipelineId",
ResourceType.PIPELINE,
System.currentTimeMillis(),
"user2"
);
readWriteOnlyAcl.getPermissions().add(
new Permission(
"user1",
SubjectType.USER,
"user2",
System.currentTimeMillis(),
ImmutableList.of(Action.READ, Action.WRITE)
)
);
Acl readWriteExecuteAcl = createAcl(
"pipelineId",
ResourceType.PIPELINE,
System.currentTimeMillis(),
"user2"
);
readWriteExecuteAcl.getPermissions().add(
new Permission(
"user1",
SubjectType.USER,
"user2",
System.currentTimeMillis(),
ImmutableList.of(Action.READ, Action.WRITE, Action.EXECUTE)
)
);
Acl noPermAcl = createAcl(
"pipelineId",
ResourceType.PIPELINE,
System.currentTimeMillis(),
"user2"
);
switch (pipelineName) {
case "readOnly":
return readOnlyAcl;
case "readWriteOnly":
return readWriteOnlyAcl;
case "readWriteExecute":
return readWriteExecuteAcl;
case "noPermAcl":
return noPermAcl;
case "name1":
case "name2":
case "name3":
case "xyz":
case "myPipeline":
case "newFromImport":
case "myPipeline1":
case "myPipeline2":
case "abc":
case "def":
return user1Acl;
}
return null;
}
};
return aclStore;
}
@Override
public void dispose(AclStoreTask aclStoreTask) {
}
}
static boolean isACLEnabled = true;
public static class RuntimeInfoTestInjector implements Factory<RuntimeInfo> {
@Singleton
@Override
public RuntimeInfo provide() {
RuntimeInfo runtimeInfo = Mockito.mock(RuntimeInfo.class);
Mockito.when(runtimeInfo.isAclEnabled()).thenReturn(isACLEnabled);
return runtimeInfo;
}
@Override
public void dispose(RuntimeInfo runtimeInfo) {
}
}
static Manager manager;
static class ManagerTestInjector implements Factory<Manager> {
public ManagerTestInjector() {
}
@Singleton
@Override
public Manager provide() {
manager = Mockito.mock(Manager.class);
try {
PipelineState pipelineState1 = new PipelineStateImpl(
"user",
"name1",
"1",
PipelineStatus.RUNNING,
"message",
-1,
new HashMap<String, Object>(),
ExecutionMode.STANDALONE,
"",
-1,
-1
);
Mockito.when(manager.getPipelineState("name1", "1")).thenReturn(pipelineState1);
PipelineState pipelineState2 = new PipelineStateImpl(
"user",
"name2",
"1",
PipelineStatus.START_ERROR,
"message",
-1,
new HashMap<String, Object>(),
ExecutionMode.STANDALONE,
"",
-1,
-1
);
Mockito.when(manager.getPipelineState("name2", "1")).thenReturn(pipelineState2);
PipelineState pipelineState3 = new PipelineStateImpl(
"user",
"name3",
"1",
PipelineStatus.RUN_ERROR,
"message",
-1,
new HashMap<String, Object>(),
ExecutionMode.STANDALONE,
"",
-1,
-1
);
Mockito.when(manager.getPipelineState("name3", "1")).thenReturn(pipelineState3);
} catch (Exception e) {
LOG.debug("Ignoring exception", e);
}
return manager;
}
@Override
public void dispose(Manager manager) {
}
}
@Test
@SuppressWarnings("unchecked")
public void testUiInfo() throws Exception {
PipelineConfiguration conf = MockStages.createPipelineConfigurationSourceProcessorTarget();
conf.getUiInfo().put("a", "A");
Response response = target("/v1/pipeline/myPipeline/uiInfo")
.request()
.post(Entity.json(Collections.EMPTY_MAP));
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals(0, response.getLength());
Mockito.verify(pipelineStore, Mockito.times(1)).saveUiInfo(Mockito.anyString(), Mockito.anyString(),
Mockito.anyMap());
}
@Test
public void testExportPipeline() {
Response response = target("/v1/pipeline/xyz/export").queryParam("rev", "1").request().get();
PipelineEnvelopeJson pipelineEnvelope = response.readEntity(PipelineEnvelopeJson.class);
Assert.assertNotNull(pipelineEnvelope);
Assert.assertNotNull(pipelineEnvelope.getPipelineConfig());
Assert.assertNotNull(pipelineEnvelope.getPipelineRules());
Assert.assertNull(pipelineEnvelope.getLibraryDefinitions());
}
@Test
public void testExportPipelineWithDefinitions() {
Response response = target("/v1/pipeline/xyz/export").queryParam("rev", "1")
.queryParam("includeLibraryDefinitions", true).request().get();
// Reading as PipelineEnvelopeJson ignores the definitions, so reading as Map
Map pipelineEnvelope = response.readEntity(Map.class);
Assert.assertNotNull(pipelineEnvelope);
Assert.assertTrue(pipelineEnvelope.containsKey("pipelineConfig"));
Assert.assertNotNull(pipelineEnvelope.get("pipelineConfig"));
Assert.assertTrue(pipelineEnvelope.containsKey("pipelineRules"));
Assert.assertNotNull(pipelineEnvelope.get("pipelineRules"));
Assert.assertTrue(pipelineEnvelope.containsKey("libraryDefinitions"));
Assert.assertNotNull(pipelineEnvelope.get("libraryDefinitions"));
}
@Test
public void testImportPipeline() {
Response response = target("/v1/pipeline/xyz/export").queryParam("rev", "1").request().get();
PipelineEnvelopeJson pipelineEnvelope = response.readEntity(PipelineEnvelopeJson.class);
response = target("/v1/pipeline/newFromImport/import")
.queryParam("rev", "1")
.request()
.post(Entity.json(pipelineEnvelope));
pipelineEnvelope = response.readEntity(PipelineEnvelopeJson.class);
Assert.assertNotNull(pipelineEnvelope);
Assert.assertNotNull(pipelineEnvelope.getPipelineConfig());
Assert.assertNotNull(pipelineEnvelope.getPipelineRules());
Assert.assertNull(pipelineEnvelope.getLibraryDefinitions());
}
@Test
public void testAddLabelsToPipelines() throws PipelineStoreException {
Response response = target("/v1/pipelines/addLabels").request()
.post(Entity.json("{\"labels\": [\"foo\", \"bar\"], \"pipelineNames\": [\"abc\", \"def\", \"nonExistent\"]}"));
MultiStatusResponseJson<String> multiStatusResponse = response.readEntity(MultiStatusResponseJson.class);
Assert.assertEquals(207, response.getStatusInfo().getStatusCode());
List<String> successEntities = multiStatusResponse.getSuccessEntities();
Assert.assertEquals(Arrays.asList("abc", "def"), successEntities);
List<String> errorMessages = multiStatusResponse.getErrorMessages();
Assert.assertEquals(Arrays.asList("Failed adding labels [foo, bar] to pipeline: nonExistent. Error: null"),
errorMessages);
}
}