1

I've encountered a problem with GeoServer REST in both 2.6.2 and 2.5.4 (though not, interestingly, in 2.3.1).

When adding a GeoTIFF with a path accessible to GeoServer, the server replies with:

The specified coverageName resttestdemis not supported

This happens when I use cURL:

curl -X POST -d '<coverage><enabled>true</enabled><metadata /><keywords /><metadataLinks /><name>resttestdem</name><title>resttestdem</title><srs>EPSG:4326</srs><projectionPolicy>REPROJECT_TO_DECLARED</projectionPolicy></coverage>' http://admin:geoserver@localhost:8080/geoserver/rest/workspaces/fake_rfe2/coveragestores/testRESTStoreGeotiff/coverages.xml --header "Content-Type:application/xml"
:The specified coverageName resttestdemis not supported

And also when I use GeoServer Manager:

08:22:15.077 [main] DEBUG httpclient.wire.header - >> "POST /geoserver/rest/workspaces/fake_rfe2/coveragestores/testRESTStoreGeotiff/coverages.xml HTTP/1.1[\r][\n]"
08:22:15.079 [main] DEBUG o.a.c.httpclient.HttpMethodBase - Adding Host request header
08:22:15.079 [main] DEBUG httpclient.wire.header - >> "Authorization: Basic YWRtaW46Z2Vvc2VydmVy[\r][\n]"
08:22:15.079 [main] DEBUG httpclient.wire.header - >> "User-Agent: Jakarta Commons-HttpClient/3.1[\r][\n]"
08:22:15.080 [main] DEBUG httpclient.wire.header - >> "Host: localhost:8080[\r][\n]"
08:22:15.080 [main] DEBUG httpclient.wire.header - >> "Content-Length: 213[\r][\n]"
08:22:15.080 [main] DEBUG httpclient.wire.header - >> "Content-Type: text/xml[\r][\n]"
08:22:15.080 [main] DEBUG httpclient.wire.header - >> "[\r][\n]"
08:22:15.081 [main] DEBUG httpclient.wire.content - >> "<coverage><enabled>true</enabled><metadata /><keywords /><metadataLinks /><name>resttestdem</name><title>resttestdem</title><srs>EPSG:4326</srs><projectionPolicy>REPROJECT_TO_DECLARED</projectionPolicy></coverage>"
08:22:15.081 [main] DEBUG o.a.c.h.m.EntityEnclosingMethod - Request body sent
08:22:15.198 [main] DEBUG httpclient.wire.header - << "HTTP/1.1 500 Internal Server Error[\r][\n]"
08:22:15.198 [main] DEBUG httpclient.wire.header - << "HTTP/1.1 500 Internal Server Error[\r][\n]"
08:22:15.198 [main] DEBUG httpclient.wire.header - << "Content-Type: text/plain[\r][\n]"
08:22:15.198 [main] DEBUG httpclient.wire.header - << "Transfer-Encoding: chunked[\r][\n]"
08:22:15.198 [main] DEBUG httpclient.wire.header - << "Server: Jetty(6.1.8)[\r][\n]"
08:22:15.199 [main] DEBUG httpclient.wire.header - << "[\r][\n]"
08:22:15.199 [main] DEBUG httpclient.wire.content - << "3"
08:22:15.199 [main] DEBUG httpclient.wire.content - << "7"
08:22:15.199 [main] DEBUG httpclient.wire.content - << "[\r]"
08:22:15.199 [main] DEBUG httpclient.wire.content - << "[\n]"
08:22:15.199 [main] DEBUG httpclient.wire.content - << ":The specified coverageName resttestdemis not supported"
08:22:15.200 [main] DEBUG httpclient.wire.content - << "[\r]"
08:22:15.200 [main] DEBUG httpclient.wire.content - << "[\n]"
08:22:15.200 [main] DEBUG httpclient.wire.content - << "0"
08:22:15.200 [main] DEBUG httpclient.wire.content - << "[\r]"
08:22:15.200 [main] DEBUG httpclient.wire.content - << "[\n]"
08:22:15.200 [main] DEBUG httpclient.wire.content - << "[\r]"
08:22:15.200 [main] DEBUG httpclient.wire.content - << "[\n]"
08:22:15.200 [main] DEBUG httpclient.wire.header - << "[\r][\n]"

When this happens, the following stacktrace appears in the server log:

Caused by: java.lang.IllegalArgumentException: The specified coverageName resttestdemis not supported
  at org.geotools.coverage.grid.io.AbstractGridCoverage2DReader.getCoordinateReferenceSystem(AbstractGridCoverage2DReader.java:820)
  at org.geoserver.catalog.CoverageDimensionCustomizerReader.getCoordinateReferenceSystem(CoverageDimensionCustomizerReader.java:317)
  at org.geoserver.catalog.SingleGridCoverage2DReader.getCoordinateReferenceSystem(SingleGridCoverage2DReader.java:151)
  at org.geoserver.catalog.CatalogBuilder.initCoverage(CatalogBuilder.java:790)
  at org.geoserver.catalog.rest.CoverageResource.handleObjectPost(CoverageResource.java:87)
  at org.geoserver.rest.ReflectiveResource.handlePost(ReflectiveResource.java:121)

Looking at AbstractGridCoverage2DReader.getCoordinateReferenceSystem:

/**
 * Retrieves the {@link GeneralEnvelope} for this {@link AbstractGridCoverage2DReader}.
 * 
 * @return the {@link GeneralEnvelope} for this {@link AbstractGridCoverage2DReader}.
 */
@Override
public CoordinateReferenceSystem getCoordinateReferenceSystem(String coverageName) {
    if (!checkName(coverageName)) {
        throw new IllegalArgumentException("The specified coverageName " + coverageName
                + "is not supported");
    }

    return crs;
}

It appears that checkName is returning false, which means that coverageName != this.coverageName or coverageName == null. Hmm.

Any ideas?

Update:

I was able to get this working with:

curl -v -u admin:geoserver -XPUT -H "Content-type: text/plain" -d "file:///Users/gregederer/dev6/EWX_SAMPLE_DATA/RFE2/monthly/data.2000.03.tiff" 'http://localhost:8080/geoserver/rest/workspaces/fake_rfe2/coveragestores/rfe2_africa_1-month-03-2000_mm_data/external.geotiff?configure=first&coverageName=rfe2_africa_1-month-03-2000_mm_data'

Followed by (to change the layer style):

curl -u admin:geoserver -XPUT -H 'Content-type: text/xml' -d '<layer><defaultStyle><name>raster</name><workspace></workspace></defaultStyle></layer>' http://localhost:8080/geoserver/rest/layers/fake_rfe2:rfe2_africa_1-month-03-2000_mm_data

I also implemented this in Java using Apache HttpComponents:

public boolean createCoverage(String workspace, String name, String path, String layerStyle) {
  boolean succeeded = false;

  try {
    URI uri = new URIBuilder()
        .setScheme(geoServerScheme)
        .setHost(geoServerHost)
        .setPort(geoServerPort)
        .setPath(geoServerPath + "/rest/workspaces/" + workspace + "/coveragestores/" + name + "/external.geotiff")
        .setParameter("configure", "first")
        .setParameter("coverageName", name)
        .build();

    StringEntity stringEntity = new StringEntity("file:///" + path,
        ContentType.create("tex/plain", "UTF-8"));

    HttpPut httpPut = new HttpPut(uri);
    httpPut.setEntity(stringEntity);

    System.out.println("Executing request " + httpPut.getRequestLine());
    CloseableHttpResponse response = httpclient.execute(httpPut);

    succeeded = response.getStatusLine().getStatusCode() == 201;
    succeeded = succeeded && updateLayerStyle(workspace, name, layerStyle);

    try {
      System.out.println("----------------------------------------");
      System.out.println(response.getStatusLine());
    } finally {
      response.close();
    }
  } catch (URISyntaxException e) {
    e.printStackTrace();
  } catch (ClientProtocolException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    try {
      httpclient.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  return succeeded;
}

public boolean updateLayerStyle(String workspace, String layerName, String styleName) {
  boolean succeeded = false;

  try {
    URI uri = new URIBuilder()
        .setScheme(geoServerScheme)
        .setHost(geoServerHost)
        .setPort(geoServerPort)
        .setPath(geoServerPath + "/rest/layers/" + workspace + ":" + layerName)
        .build();

    StringEntity stringEntity = new StringEntity("<layer><defaultStyle><name>" + styleName + "</name><workspace></workspace></defaultStyle></layer>",
        ContentType.create("application/xml", "UTF-8"));

    HttpPut httpPut = new HttpPut(uri);
    httpPut.setEntity(stringEntity);

    System.out.println("Executing request " + httpPut.getRequestLine());
    CloseableHttpResponse response = httpclient.execute(httpPut);

    succeeded = response.getStatusLine().getStatusCode() == 200;

    try {
      System.out.println("----------------------------------------");
      System.out.println(response.getStatusLine());
    } finally {
      response.close();
    }
  } catch (URISyntaxException e) {
    e.printStackTrace();
  } catch (ClientProtocolException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    try {
      httpclient.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  return succeeded;
}

Hope this workaround helps someone.

1

I also came into this issue when upgrading from 2.1 to 2.6.

We are posting nativeName (file name) and name (layer name) to the rest API.

The problem is that for >= 2.4 the CatalogBuilder is called via

coverage = builder.buildCoverage(name);

So within this method, there is no possibility to distinguish between name and nativeName.

If you want to fix this yourself and do not mind building GeoServer yourself, you could do something like this within CoverageResource.handleObjectPost (without changing signatures):

// Code omitted ...

String name = coverage.getName();
String nativeName = coverage.getNativeName();
CatalogBuilder builder = new CatalogBuilder(catalog);
CoverageStoreInfo store = coverage.getStore();
builder.setStore(store);

// We handle 2 different cases here
if (!isNew) {
    // Configuring a partially defined coverage
    builder.initCoverage(coverage, name);
} else {
    // Configuring a brand new coverage (only name has been specified)
    coverage = builder.buildCoverage(nativeName);
    coverage.setName(name);
}

// Code omitted ...

We are always setting name and nativeName via Xml, so this does not apply to us, but it might be good to check for null values, something like CatalogBuilder.initResourceInfo does...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.