You may have corrupted artifacts (e.g. an artifact with a wrong content as a result of a DNS error) that got cached into Artifactory. By default, Artifactory keeps your repositories healthy by refusing POMs with incorrect coordinates (path). If the groupId:artifactId:version information inside the POM does not match the deployed path, Artifactory rejects the deployment with a "409 Conflict" error. You can disable this behavior by setting the Suppress POM Consistency checkbox.
Below is a sample Artifactory Query Language (AQL) query to help identify files that are possibly corrupted.
items.find( {"$or":[ { "$and":[ {"type":"file"}, {"size":{"$lte":"1364"}}, {"repo":"remote-cache"}, {"name":{"$ne":"maven-metadata.xml"}}, {"name":{"$nmatch":"*.pom"}}, {"name":{"$nmatch":"*.asc"}} ] }, { "$and":[ {"type":"file"}, {"size":"0"}, {"repo":"remote-cache"} ] }, { "$and":[ {"type":"file"}, {"archive.entry.name":{"$eq":null}}, {"name":{"$match":"*.jar"}}, {"repo":"remote-cache"} ] } ] } ) .sort({"$desc":["name"]})
The AQL example above will search for any files that are in remote-cache (cache of "remote" repository) that meet ANY of the following condition
- files with file size that are less than or equal to 1364 bytes, except maven-metadata.xml, *.pom, *.asc
- files that has 0 file size
- *.jar (archive) files contain null
You may save the JSON file above as a file (e.g. cleanaql) then use it for the command below
curl -L??-X POST -H"Content-type:text/plain" -uadmin:password --data-binary @cleanaql??https://my-artifactory/artifactory/api/search/aql >aql-result.json
After examining the output (aql-result.json), you may use below groovy script to delete the artifacts found by the AQL above.
import groovy.json.JsonSlurper import org.jfrog.artifactory.client.Artifactory import org.jfrog.artifactory.client.ArtifactoryClient /** * Created by eli@jfrog on 03/03/2016. */ class DeleteFiles { final static String ARTIFACTORY_URL = 'https://my_artifactory/artifactory' static String adminUser = '*' static String adminPassword = '*' static Artifactory artifactoryClient = ArtifactoryClient.create(ARTIFACTORY_URL, adminUser, adminPassword) public static void main(String[] args) { def json = new JsonSlurper().parse(new File('/PATH-TO-FILE/aql-result.json')) json.results.each{it-> String path = "${it.path}/${it.name}" println "deleteing path $path" artifactoryClient.repositories().repository("remote-cache").delete(path) } } }