use of io.cdap.cdap.proto.artifact.PluginInfo in project cdap by cdapio.
the class ArtifactHttpHandler method getArtifactPlugin.
@GET
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}/" + "versions/{artifact-version}/extensions/{plugin-type}/plugins/{plugin-name}")
public void getArtifactPlugin(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("artifact-name") String artifactName, @PathParam("artifact-version") String artifactVersion, @PathParam("plugin-type") String pluginType, @PathParam("plugin-name") String pluginName, @QueryParam("scope") @DefaultValue("user") final String scope, @QueryParam("artifactName") final String pluginArtifactName, @QueryParam("artifactVersion") String pluginVersion, @QueryParam("artifactScope") final String pluginScope, @QueryParam("limit") @DefaultValue("2147483647") String limit, @QueryParam("order") @DefaultValue("UNORDERED") String order) throws NamespaceNotFoundException, BadRequestException, ArtifactNotFoundException, InvalidArtifactRangeException {
NamespaceId namespace = Ids.namespace(namespaceId);
NamespaceId artifactNamespace = validateAndGetScopedNamespace(namespace, scope);
final NamespaceId pluginArtifactNamespace = validateAndGetScopedNamespace(namespace, pluginScope);
ArtifactId parentArtifactId = validateAndGetArtifactId(artifactNamespace, artifactName, artifactVersion);
final ArtifactVersionRange pluginRange = pluginVersion == null ? null : ArtifactVersionRange.parse(pluginVersion);
int limitNumber = Integer.parseInt(limit);
limitNumber = limitNumber <= 0 ? Integer.MAX_VALUE : limitNumber;
ArtifactSortOrder sortOrder = ArtifactSortOrder.valueOf(order);
Predicate<ArtifactId> predicate = new Predicate<ArtifactId>() {
@Override
public boolean apply(ArtifactId input) {
// by default, the scoped namespace is for USER scope
return (((pluginScope == null && NamespaceId.SYSTEM.equals(input.getParent())) || pluginArtifactNamespace.equals(input.getParent())) && (pluginArtifactName == null || pluginArtifactName.equals(input.getArtifact())) && (pluginRange == null || pluginRange.versionIsInRange(new ArtifactVersion(input.getVersion()))));
}
};
try {
SortedMap<ArtifactDescriptor, PluginClass> plugins = artifactRepository.getPlugins(namespace, Id.Artifact.fromEntityId(parentArtifactId), pluginType, pluginName, predicate, limitNumber, sortOrder);
List<PluginInfo> pluginInfos = Lists.newArrayList();
// flatten the map
for (Map.Entry<ArtifactDescriptor, PluginClass> pluginsEntry : plugins.entrySet()) {
ArtifactDescriptor pluginArtifact = pluginsEntry.getKey();
ArtifactSummary pluginArtifactSummary = ArtifactSummary.from(pluginArtifact.getArtifactId());
PluginClass pluginClass = pluginsEntry.getValue();
try {
capabilityReader.checkAllEnabled(pluginClass.getRequirements().getCapabilities());
} catch (CapabilityNotAvailableException e) {
LOG.debug("Skipping plugin {} because of disabled capability", pluginClass, e);
continue;
}
pluginInfos.add(new PluginInfo(pluginClass, pluginArtifactSummary));
}
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(pluginInfos));
} catch (PluginNotExistsException e) {
responder.sendString(HttpResponseStatus.NOT_FOUND, e.getMessage());
} catch (IOException e) {
LOG.error("Exception looking up plugins for artifact {}", parentArtifactId, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error reading plugins for the artifact from the store.");
}
}
use of io.cdap.cdap.proto.artifact.PluginInfo in project cdap by cdapio.
the class ArtifactClientTestRun method testArtifacts.
@Test
public void testArtifacts() throws Exception {
// add 2 versions of an artifact with an application
ArtifactId myapp1Id = NamespaceId.DEFAULT.artifact("myapp", "1.0.0");
ArtifactId myapp2Id = NamespaceId.DEFAULT.artifact("myapp", "2.0.0");
LocalLocationFactory locationFactory = new LocalLocationFactory(TMP_FOLDER.newFolder());
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(ManifestFields.BUNDLE_VERSION, "2.0.0");
final Location appJarLoc = AppJarHelper.createDeploymentJar(locationFactory, MyApp.class, manifest);
ContentProvider<InputStream> contentProvider = appJarLoc::getInputStream;
artifactClient.add(myapp1Id.getParent(), myapp1Id.getArtifact(), contentProvider, myapp1Id.getVersion());
// add some properties
Map<String, String> myapp1Properties = ImmutableMap.of("k1", "v1");
artifactClient.writeProperties(myapp1Id, myapp1Properties);
// let it derive version from jar manifest, which has bundle-version at 2.0.0
artifactClient.add(myapp2Id.getParent(), myapp2Id.getArtifact(), contentProvider, null, null);
// add some properties
Map<String, String> myapp2Properties = ImmutableMap.of("k1", "v1", "k2", "v2");
artifactClient.writeProperties(myapp2Id, myapp2Properties);
// add an artifact that contains a plugin, but only extends myapp-2.0.0
ArtifactId pluginId = NamespaceId.DEFAULT.artifact("myapp-plugins", "2.0.0");
manifest = new Manifest();
manifest.getMainAttributes().put(ManifestFields.EXPORT_PACKAGE, Plugin1.class.getPackage().getName());
final Location pluginJarLoc = PluginJarHelper.createPluginJar(locationFactory, manifest, Plugin1.class);
contentProvider = pluginJarLoc::getInputStream;
Set<ArtifactRange> parents = Sets.newHashSet(new ArtifactRange(myapp2Id.getParent().getNamespace(), myapp2Id.getArtifact(), new ArtifactVersion(myapp2Id.getVersion()), new ArtifactVersion("3.0.0")));
Set<PluginClass> additionalPlugins = Sets.newHashSet(PluginClass.builder().setName("mysql").setType("jdbc").setDescription("").setClassName(Plugin1.class.getName()).build());
artifactClient.add(pluginId.getParent(), pluginId.getArtifact(), contentProvider, pluginId.getVersion(), parents, additionalPlugins);
ArtifactSummary myapp1Summary = new ArtifactSummary(myapp1Id.getArtifact(), myapp1Id.getVersion());
ArtifactSummary myapp2Summary = new ArtifactSummary(myapp2Id.getArtifact(), myapp2Id.getVersion());
ArtifactSummary pluginArtifactSummary = new ArtifactSummary(pluginId.getArtifact(), pluginId.getVersion());
Set<ArtifactSummary> artifacts = Sets.newHashSet(artifactClient.list(NamespaceId.DEFAULT));
Assert.assertEquals(Sets.newHashSet(myapp1Summary, myapp2Summary, pluginArtifactSummary), artifacts);
// list all artifacts named 'myapp'
Assert.assertEquals(Sets.newHashSet(myapp1Summary, myapp2Summary), Sets.newHashSet(artifactClient.listVersions(NamespaceId.DEFAULT, myapp1Id.getArtifact())));
// list all artifacts named 'myapp-plugins'
Assert.assertEquals(Sets.newHashSet(pluginArtifactSummary), Sets.newHashSet(artifactClient.listVersions(NamespaceId.DEFAULT, pluginId.getArtifact())));
// artifacts should be in user scope
try {
artifactClient.listVersions(NamespaceId.DEFAULT, pluginId.getArtifact(), ArtifactScope.SYSTEM);
Assert.fail();
} catch (ArtifactNotFoundException e) {
// expected
}
// get info about specific artifacts
Schema myAppConfigSchema = new ReflectionSchemaGenerator(false).generate(MyApp.Conf.class);
ArtifactClasses myAppClasses = ArtifactClasses.builder().addApp(new ApplicationClass(MyApp.class.getName(), "", myAppConfigSchema)).build();
// test get myapp-1.0.0
ArtifactInfo myapp1Info = new ArtifactInfo(myapp1Id.getArtifact(), myapp1Id.getVersion(), ArtifactScope.USER, myAppClasses, myapp1Properties);
Assert.assertEquals(myapp1Info, artifactClient.getArtifactInfo(myapp1Id));
// test get myapp-2.0.0
ArtifactInfo myapp2Info = new ArtifactInfo(myapp2Id.getArtifact(), myapp2Id.getVersion(), ArtifactScope.USER, myAppClasses, myapp2Properties);
Assert.assertEquals(myapp2Info, artifactClient.getArtifactInfo(myapp2Id));
// test overwriting properties
myapp2Properties = ImmutableMap.of("k1", "v3", "k5", "v5");
artifactClient.writeProperties(myapp2Id, myapp2Properties);
Assert.assertEquals(myapp2Properties, artifactClient.getArtifactInfo(myapp2Id).getProperties());
// test deleting property
artifactClient.deleteProperty(myapp2Id, "k1");
Assert.assertEquals(ImmutableMap.of("k5", "v5"), artifactClient.getArtifactInfo(myapp2Id).getProperties());
// test writing property
artifactClient.writeProperty(myapp2Id, "k5", "v4");
Assert.assertEquals(ImmutableMap.of("k5", "v4"), artifactClient.getArtifactInfo(myapp2Id).getProperties());
// test deleting properties
artifactClient.deleteProperties(myapp2Id);
Assert.assertTrue(artifactClient.getArtifactInfo(myapp2Id).getProperties().isEmpty());
// test get myapp-plugins-2.0.0
Map<String, PluginPropertyField> props = ImmutableMap.of("x", new PluginPropertyField("x", "", "int", true, false));
ArtifactClasses pluginClasses = ArtifactClasses.builder().addPlugin(PluginClass.builder().setName("plugin1").setType("callable").setDescription("p1 description").setClassName(Plugin1.class.getName()).setConfigFieldName("conf").setProperties(props).build()).addPlugins(additionalPlugins).build();
ArtifactInfo pluginArtifactInfo = new ArtifactInfo(pluginId.getArtifact(), pluginId.getVersion(), ArtifactScope.USER, pluginClasses, ImmutableMap.<String, String>of());
Assert.assertEquals(pluginArtifactInfo, artifactClient.getArtifactInfo(pluginId));
// test get all app classes in namespace
Set<ApplicationClassSummary> expectedSummaries = ImmutableSet.of(new ApplicationClassSummary(myapp1Summary, MyApp.class.getName()), new ApplicationClassSummary(myapp2Summary, MyApp.class.getName()));
Set<ApplicationClassSummary> appClassSummaries = Sets.newHashSet(artifactClient.getApplicationClasses(NamespaceId.DEFAULT));
Assert.assertEquals(expectedSummaries, appClassSummaries);
// test get all app classes in namespace with name MyApp.class.getName()
Set<ApplicationClassInfo> appClassInfos = Sets.newHashSet(artifactClient.getApplicationClasses(NamespaceId.DEFAULT, MyApp.class.getName()));
Set<ApplicationClassInfo> expectedInfos = ImmutableSet.of(new ApplicationClassInfo(myapp1Summary, MyApp.class.getName(), myAppConfigSchema), new ApplicationClassInfo(myapp2Summary, MyApp.class.getName(), myAppConfigSchema));
Assert.assertEquals(expectedInfos, appClassInfos);
// test get plugin types for myapp-1.0.0. should be empty, since plugins only extends versions [2.0.0 - 3.0.0)
Assert.assertTrue(artifactClient.getPluginTypes(myapp1Id).isEmpty());
// test get plugin types for myapp-2.0.0
Assert.assertEquals(Lists.newArrayList("callable", "jdbc"), artifactClient.getPluginTypes(myapp2Id));
// test get plugins of type callable for myapp-2.0.0
PluginSummary pluginSummary = new PluginSummary("plugin1", "callable", null, Plugin1.class.getName(), pluginArtifactSummary, "p1 description");
Assert.assertEquals(Sets.newHashSet(pluginSummary), Sets.newHashSet(artifactClient.getPluginSummaries(myapp2Id, "callable")));
// no plugins of type "runnable"
Assert.assertTrue(artifactClient.getPluginSummaries(myapp2Id, "runnable").isEmpty());
// test get plugin details for plugin1 for myapp-2.0.0
PluginInfo pluginInfo = new PluginInfo("plugin1", "callable", null, Plugin1.class.getName(), "conf", pluginArtifactSummary, props, "p1 description");
Assert.assertEquals(Sets.newHashSet(pluginInfo), Sets.newHashSet(artifactClient.getPluginInfo(myapp2Id, "callable", "plugin1")));
}
use of io.cdap.cdap.proto.artifact.PluginInfo in project cdap by cdapio.
the class ArtifactClient method getPluginInfo.
/**
* Gets all the plugins of the given type and name available to the given artifact.
*
* @param artifactId the id of the artifact to get
* @param pluginType the type of plugins to get
* @param pluginName the name of the plugins to get
* @param scope the scope of the artifact
* @return list of {@link PluginInfo}
* @throws NotFoundException if the given artifact does not exist or plugins for that artifact do not exist
* @throws IOException if a network error occurred
* @throws UnauthenticatedException if the request is not authorized successfully in the gateway server
*/
public List<PluginInfo> getPluginInfo(ArtifactId artifactId, String pluginType, String pluginName, ArtifactScope scope) throws IOException, UnauthenticatedException, NotFoundException, UnauthorizedException {
String path = String.format("artifacts/%s/versions/%s/extensions/%s/plugins/%s?scope=%s", artifactId.getArtifact(), artifactId.getVersion(), pluginType, pluginName, scope.name());
URL url = config.resolveNamespacedURLV3(artifactId.getParent(), path);
HttpResponse response = restClient.execute(HttpMethod.GET, url, config.getAccessToken(), HttpURLConnection.HTTP_NOT_FOUND);
if (response.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
throw new NotFoundException(response.getResponseBodyAsString());
}
return ObjectResponse.<List<PluginInfo>>fromJsonBody(response, PLUGIN_INFOS_TYPE).getResponseObject();
}
use of io.cdap.cdap.proto.artifact.PluginInfo in project cdap by caskdata.
the class RemotePluginFinder method findPlugin.
@Override
public Map.Entry<ArtifactDescriptor, PluginClass> findPlugin(NamespaceId pluginNamespaceId, ArtifactId parentArtifactId, String pluginType, String pluginName, PluginSelector selector) throws PluginNotExistsException {
try {
return Retries.callWithRetries(() -> {
List<PluginInfo> infos = getPlugins(pluginNamespaceId, parentArtifactId, pluginType, pluginName);
if (infos.isEmpty()) {
throw new PluginNotExistsException(pluginNamespaceId, pluginType, pluginName);
}
SortedMap<io.cdap.cdap.api.artifact.ArtifactId, PluginClass> plugins = new TreeMap<>();
for (PluginInfo info : infos) {
ArtifactSummary artifactSummary = info.getArtifact();
io.cdap.cdap.api.artifact.ArtifactId pluginArtifactId = new io.cdap.cdap.api.artifact.ArtifactId(artifactSummary.getName(), new ArtifactVersion(artifactSummary.getVersion()), artifactSummary.getScope());
PluginClass pluginClass = PluginClass.builder().setName(info.getName()).setType(info.getType()).setDescription(info.getDescription()).setClassName(info.getClassName()).setProperties(info.getProperties()).setConfigFieldName(info.getConfigFieldName()).build();
plugins.put(pluginArtifactId, pluginClass);
}
Map.Entry<io.cdap.cdap.api.artifact.ArtifactId, PluginClass> selected = selector.select(plugins);
if (selected == null) {
throw new PluginNotExistsException(pluginNamespaceId, pluginType, pluginName);
}
Location artifactLocation = getArtifactLocation(Artifacts.toProtoArtifactId(pluginNamespaceId, selected.getKey()));
return Maps.immutableEntry(new ArtifactDescriptor(pluginNamespaceId.getEntityName(), selected.getKey(), artifactLocation), selected.getValue());
}, retryStrategy);
} catch (PluginNotExistsException e) {
throw e;
} catch (ArtifactNotFoundException e) {
throw new PluginNotExistsException(pluginNamespaceId, pluginType, pluginName);
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
use of io.cdap.cdap.proto.artifact.PluginInfo in project cdap by caskdata.
the class ArtifactHttpHandler method getArtifactPlugin.
@GET
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}/" + "versions/{artifact-version}/extensions/{plugin-type}/plugins/{plugin-name}")
public void getArtifactPlugin(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("artifact-name") String artifactName, @PathParam("artifact-version") String artifactVersion, @PathParam("plugin-type") String pluginType, @PathParam("plugin-name") String pluginName, @QueryParam("scope") @DefaultValue("user") final String scope, @QueryParam("artifactName") final String pluginArtifactName, @QueryParam("artifactVersion") String pluginVersion, @QueryParam("artifactScope") final String pluginScope, @QueryParam("limit") @DefaultValue("2147483647") String limit, @QueryParam("order") @DefaultValue("UNORDERED") String order) throws NamespaceNotFoundException, BadRequestException, ArtifactNotFoundException, InvalidArtifactRangeException {
NamespaceId namespace = Ids.namespace(namespaceId);
NamespaceId artifactNamespace = validateAndGetScopedNamespace(namespace, scope);
final NamespaceId pluginArtifactNamespace = validateAndGetScopedNamespace(namespace, pluginScope);
ArtifactId parentArtifactId = validateAndGetArtifactId(artifactNamespace, artifactName, artifactVersion);
final ArtifactVersionRange pluginRange = pluginVersion == null ? null : ArtifactVersionRange.parse(pluginVersion);
int limitNumber = Integer.parseInt(limit);
limitNumber = limitNumber <= 0 ? Integer.MAX_VALUE : limitNumber;
ArtifactSortOrder sortOrder = ArtifactSortOrder.valueOf(order);
Predicate<ArtifactId> predicate = new Predicate<ArtifactId>() {
@Override
public boolean apply(ArtifactId input) {
// by default, the scoped namespace is for USER scope
return (((pluginScope == null && NamespaceId.SYSTEM.equals(input.getParent())) || pluginArtifactNamespace.equals(input.getParent())) && (pluginArtifactName == null || pluginArtifactName.equals(input.getArtifact())) && (pluginRange == null || pluginRange.versionIsInRange(new ArtifactVersion(input.getVersion()))));
}
};
try {
SortedMap<ArtifactDescriptor, PluginClass> plugins = artifactRepository.getPlugins(namespace, Id.Artifact.fromEntityId(parentArtifactId), pluginType, pluginName, predicate, limitNumber, sortOrder);
List<PluginInfo> pluginInfos = Lists.newArrayList();
// flatten the map
for (Map.Entry<ArtifactDescriptor, PluginClass> pluginsEntry : plugins.entrySet()) {
ArtifactDescriptor pluginArtifact = pluginsEntry.getKey();
ArtifactSummary pluginArtifactSummary = ArtifactSummary.from(pluginArtifact.getArtifactId());
PluginClass pluginClass = pluginsEntry.getValue();
try {
capabilityReader.checkAllEnabled(pluginClass.getRequirements().getCapabilities());
} catch (CapabilityNotAvailableException e) {
LOG.debug("Skipping plugin {} because of disabled capability", pluginClass, e);
continue;
}
pluginInfos.add(new PluginInfo(pluginClass, pluginArtifactSummary));
}
responder.sendJson(HttpResponseStatus.OK, GSON.toJson(pluginInfos));
} catch (PluginNotExistsException e) {
responder.sendString(HttpResponseStatus.NOT_FOUND, e.getMessage());
} catch (IOException e) {
LOG.error("Exception looking up plugins for artifact {}", parentArtifactId, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error reading plugins for the artifact from the store.");
}
}
Aggregations