/** * Copyright (c) 2008-2011 Sonatype, Inc. * All rights reserved. Includes the third-party code listed at http://www.sonatype.com/products/nexus/attributions. * * This program is free software: you can redistribute it and/or modify it only under the terms of the GNU Affero General * Public License Version 3 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License Version 3 * for more details. * * You should have received a copy of the GNU Affero General Public License Version 3 along with this program. If not, see * http://www.gnu.org/licenses. * * Sonatype Nexus (TM) Open Source Version is available from Sonatype, Inc. Sonatype and Sonatype Nexus are trademarks of * Sonatype, Inc. Apache Maven is a trademark of the Apache Foundation. M2Eclipse is a trademark of the Eclipse Foundation. * All other trademarks are the property of their respective owners. */ package org.sonatype.nexus.test.utils; import java.io.IOException; import java.util.List; import org.apache.log4j.Logger; import org.restlet.data.MediaType; import org.restlet.data.Method; import org.restlet.data.Response; import org.restlet.data.Status; import org.sonatype.nexus.configuration.model.CRepository; import org.sonatype.nexus.integrationtests.AbstractNexusIntegrationTest; import org.sonatype.nexus.integrationtests.RequestFacade; import org.sonatype.nexus.proxy.maven.maven2.M2LayoutedM1ShadowRepositoryConfiguration; import org.sonatype.nexus.proxy.maven.maven2.M2RepositoryConfiguration; import org.sonatype.nexus.proxy.repository.Repository; import org.sonatype.nexus.proxy.repository.ShadowRepository; import org.sonatype.nexus.rest.model.ContentListResourceResponse; import org.sonatype.nexus.rest.model.RepositoryBaseResource; import org.sonatype.nexus.rest.model.RepositoryListResource; import org.sonatype.nexus.rest.model.RepositoryListResourceResponse; import org.sonatype.nexus.rest.model.RepositoryResource; import org.sonatype.nexus.rest.model.RepositoryResourceResponse; import org.sonatype.nexus.rest.model.RepositoryShadowResource; import org.sonatype.nexus.rest.model.RepositoryStatusResource; import org.sonatype.nexus.rest.model.RepositoryStatusResourceResponse; import org.sonatype.plexus.rest.representation.XStreamRepresentation; import org.testng.Assert; import com.thoughtworks.xstream.XStream; public class RepositoryMessageUtil extends ITUtil { public static final String ALL_SERVICE_PART = RequestFacade.SERVICE_LOCAL + "all_repositories"; public static final String SERVICE_PART = RequestFacade.SERVICE_LOCAL + "repositories"; private XStream xstream; private MediaType mediaType; private static final Logger LOG = Logger.getLogger( RepositoryMessageUtil.class ); public RepositoryMessageUtil( AbstractNexusIntegrationTest test, XStream xstream, MediaType mediaType ) { super( test ); this.xstream = xstream; this.mediaType = mediaType; } public RepositoryBaseResource createRepository( RepositoryBaseResource repo ) throws IOException { return createRepository( repo, true ); } public RepositoryBaseResource createRepository( RepositoryBaseResource repo, boolean validate ) throws IOException { Response response = this.sendMessage( Method.POST, repo ); if ( !response.getStatus().isSuccess() ) { String responseText = response.getEntity().getText(); Assert.fail( "Could not create Repository: " + response.getStatus() + ":\n" + responseText ); } RepositoryBaseResource responseResource = this.getRepositoryBaseResourceFromResponse( response ); if ( validate ) { this.validateResourceResponse( repo, responseResource ); } return responseResource; } public void validateResourceResponse( RepositoryBaseResource repo, RepositoryBaseResource responseResource ) throws IOException { Assert.assertEquals( repo.getId(), responseResource.getId() ); Assert.assertEquals( repo.getName(), responseResource.getName() ); // Assert.assertEquals( repo.getDefaultLocalStorageUrl(), responseResource.getDefaultLocalStorageUrl() ); // // TODO: add check for this // format is not used anymore, removing the check // Assert.assertEquals( repo.getFormat(), responseResource.getFormat() ); Assert.assertEquals( repo.getRepoType(), responseResource.getRepoType() ); if ( repo.getRepoType().equals( "virtual" ) ) { // check mirror RepositoryShadowResource expected = (RepositoryShadowResource) repo; RepositoryShadowResource actual = (RepositoryShadowResource) responseResource; Assert.assertEquals( expected.getShadowOf(), actual.getShadowOf() ); } else { RepositoryResource expected = (RepositoryResource) repo; RepositoryResource actual = (RepositoryResource) responseResource; // Assert.assertEquals( expected.getChecksumPolicy(), actual.getChecksumPolicy() ); // TODO: sometimes the storage dir ends with a '/' SEE: NEXUS-542 if ( actual.getDefaultLocalStorageUrl().endsWith( "/" ) ) { Assert.assertTrue( actual.getDefaultLocalStorageUrl().endsWith( "/storage/" + repo.getId() + "/" ), "Unexpected defaultLocalStorage: <expected to end with> " + "/storage/" + repo.getId() + "/ <actual>" + actual.getDefaultLocalStorageUrl() ); } // NOTE one of these blocks should be removed else { Assert.assertTrue( actual.getDefaultLocalStorageUrl().endsWith( "/storage/" + repo.getId() ), "Unexpected defaultLocalStorage: <expected to end with> " + "/storage/" + repo.getId() + " <actual>" + actual.getDefaultLocalStorageUrl() ); } Assert.assertEquals( expected.getNotFoundCacheTTL(), actual.getNotFoundCacheTTL() ); // Assert.assertEquals( expected.getOverrideLocalStorageUrl(), actual.getOverrideLocalStorageUrl() ); if ( expected.getRemoteStorage() == null ) { Assert.assertNull( actual.getRemoteStorage() ); } else { Assert.assertEquals( expected.getRemoteStorage().getRemoteStorageUrl(), actual.getRemoteStorage().getRemoteStorageUrl() ); } Assert.assertEquals( expected.getRepoPolicy(), actual.getRepoPolicy() ); } // check nexus.xml this.validateRepoInNexusConfig( responseResource ); } public RepositoryBaseResource getRepository( String repoId ) throws IOException { Response response = RequestFacade.doGetRequest( SERVICE_PART + "/" + repoId ); String responseText = response.getEntity().getText(); if ( response.getStatus().isError() ) { Assert.fail( "Error on request: " + response.getStatus() + "\n" + responseText ); } LOG.debug( "responseText: \n" + responseText ); // this should use call to: getResourceFromResponse XStreamRepresentation representation = new XStreamRepresentation( XStreamFactory.getXmlXStream(), responseText, MediaType.APPLICATION_XML ); RepositoryResourceResponse resourceResponse = (RepositoryResourceResponse) representation.getPayload( new RepositoryResourceResponse() ); return resourceResponse.getData(); } public RepositoryBaseResource updateRepo( RepositoryBaseResource repo ) throws IOException { return updateRepo( repo, true ); } public RepositoryBaseResource updateRepo( RepositoryBaseResource repo, boolean validate ) throws IOException { Response response = this.sendMessage( Method.PUT, repo ); if ( !response.getStatus().isSuccess() ) { String responseText = response.getEntity().getText(); Assert.fail( "Could not update user: " + response.getStatus() + "\n" + responseText ); } RepositoryBaseResource responseResource = this.getRepositoryBaseResourceFromResponse( response ); if ( validate ) { this.validateResourceResponse( repo, responseResource ); } return responseResource; } public Response sendMessage( Method method, RepositoryBaseResource resource, String id ) throws IOException { if ( resource != null && resource.getProviderRole() == null ) { if ( "virtual".equals( resource.getRepoType() ) ) { resource.setProviderRole( ShadowRepository.class.getName() ); } else { resource.setProviderRole( Repository.class.getName() ); } } XStreamRepresentation representation = new XStreamRepresentation( xstream, "", mediaType ); String idPart = ( method == Method.POST ) ? "" : "/" + id; String serviceURI = SERVICE_PART + idPart; RepositoryResourceResponse repoResponseRequest = new RepositoryResourceResponse(); repoResponseRequest.setData( resource ); // now set the payload representation.setPayload( repoResponseRequest ); LOG.debug( "sendMessage: " + representation.getText() ); return RequestFacade.sendMessage( serviceURI, method, representation ); } public Response sendMessage( Method method, RepositoryBaseResource resource ) throws IOException { return this.sendMessage( method, resource, resource.getId() ); } /** * This should be replaced with a REST Call, but the REST client does not set the Accept correctly on GET's/ * * @return * @throws IOException */ public List<RepositoryListResource> getList() throws IOException { String responseText = RequestFacade.doGetRequest( SERVICE_PART ).getEntity().getText(); LOG.debug( "responseText: \n" + responseText ); XStreamRepresentation representation = new XStreamRepresentation( XStreamFactory.getXmlXStream(), responseText, MediaType.APPLICATION_XML ); RepositoryListResourceResponse resourceResponse = (RepositoryListResourceResponse) representation.getPayload( new RepositoryListResourceResponse() ); return resourceResponse.getData(); } public List<RepositoryListResource> getAllList() throws IOException { String responseText = RequestFacade.doGetRequest( ALL_SERVICE_PART ).getEntity().getText(); LOG.debug( "responseText: \n" + responseText ); XStreamRepresentation representation = new XStreamRepresentation( XStreamFactory.getXmlXStream(), responseText, MediaType.APPLICATION_XML ); RepositoryListResourceResponse resourceResponse = (RepositoryListResourceResponse) representation.getPayload( new RepositoryListResourceResponse() ); return resourceResponse.getData(); } public RepositoryBaseResource getRepositoryBaseResourceFromResponse( Response response ) throws IOException { String responseString = response.getEntity().getText(); LOG.debug( " getRepositoryBaseResourceFromResponse: " + responseString ); XStreamRepresentation representation = new XStreamRepresentation( xstream, responseString, mediaType ); RepositoryResourceResponse resourceResponse = (RepositoryResourceResponse) representation.getPayload( new RepositoryResourceResponse() ); return resourceResponse.getData(); } public RepositoryResource getResourceFromResponse( Response response ) throws IOException { return (RepositoryResource) getRepositoryBaseResourceFromResponse( response ); } private void validateRepoInNexusConfig( RepositoryBaseResource repo ) throws IOException { if ( repo.getRepoType().equals( "virtual" ) ) { // check mirror RepositoryShadowResource expected = (RepositoryShadowResource) repo; CRepository cRepo = getTest().getNexusConfigUtil().getRepo( repo.getId() ); M2LayoutedM1ShadowRepositoryConfiguration cShadowRepo = getTest().getNexusConfigUtil().getRepoShadow( repo.getId() ); Assert.assertEquals( expected.getShadowOf(), cShadowRepo.getMasterRepositoryId() ); Assert.assertEquals( expected.getId(), cRepo.getId() ); Assert.assertEquals( expected.getName(), cRepo.getName() ); // cstamas: This is nonsense, this starts in-process (HERE) of nexus internals while IT runs a nexus too, // and they start/try to use same FS resources! // ContentClass expectedCc = // repositoryTypeRegistry.getRepositoryContentClass( cRepo.getProviderRole(), cRepo.getProviderHint() ); // Assert.assertNotNull( expectedCc, // "Unknown shadow repo type='" + cRepo.getProviderRole() + cRepo.getProviderHint() // + "'!" ); // Assert.assertEquals( expected.getFormat(), expectedCc.getId() ); } else { RepositoryResource expected = (RepositoryResource) repo; CRepository cRepo = getTest().getNexusConfigUtil().getRepo( repo.getId() ); Assert.assertEquals( cRepo.getId(), expected.getId() ); Assert.assertEquals( cRepo.getName(), expected.getName() ); // cstamas: This is nonsense, this starts in-process (HERE) of nexus internals while IT runs a nexus too, // and they start/try to use same FS resources! // ContentClass expectedCc = // repositoryTypeRegistry.getRepositoryContentClass( cRepo.getProviderRole(), cRepo.getProviderHint() ); // Assert.assertNotNull( expectedCc, "Unknown repo type='" + cRepo.getProviderRole() + // cRepo.getProviderHint() // + "'!" ); // Assert.assertEquals( expected.getFormat(), expectedCc.getId() ); Assert.assertEquals( expected.getNotFoundCacheTTL(), cRepo.getNotFoundCacheTTL() ); if ( expected.getOverrideLocalStorageUrl() == null ) { Assert.assertNull( cRepo.getLocalStorage().getUrl(), "Expected CRepo localstorage url not be set, because it is the default." ); } else { String actualLocalStorage = cRepo.getLocalStorage().getUrl().endsWith( "/" ) ? cRepo.getLocalStorage().getUrl() : cRepo.getLocalStorage().getUrl() + "/"; String overridLocalStorage = expected.getOverrideLocalStorageUrl().endsWith( "/" ) ? expected.getOverrideLocalStorageUrl() : expected.getOverrideLocalStorageUrl() + "/"; Assert.assertEquals( overridLocalStorage, actualLocalStorage ); } if ( expected.getRemoteStorage() == null ) { Assert.assertNull( cRepo.getRemoteStorage() ); } else { Assert.assertEquals( expected.getRemoteStorage().getRemoteStorageUrl(), cRepo.getRemoteStorage().getUrl() ); } // check maven repo props (for not just check everything that is a Repository if ( expected.getProvider().matches( "maven[12]" ) ) { M2RepositoryConfiguration cM2Repo = getTest().getNexusConfigUtil().getM2Repo( repo.getId() ); if ( expected.getChecksumPolicy() != null ) { Assert.assertEquals( expected.getChecksumPolicy(), cM2Repo.getChecksumPolicy().name() ); } Assert.assertEquals( expected.getRepoPolicy(), cM2Repo.getRepositoryPolicy().name() ); } } } public static void updateIndexes( String... repositories ) throws Exception { reindex( repositories, false ); } private static void reindex( String[] repositories, boolean incremental ) throws IOException, Exception { for ( String repo : repositories ) { String serviceURI; if ( incremental ) { serviceURI = "service/local/data_incremental_index/repositories/" + repo + "/content"; } else { serviceURI = "service/local/data_index/repositories/" + repo + "/content"; } Response response = RequestFacade.sendMessage( serviceURI, Method.DELETE ); Status status = response.getStatus(); Assert.assertTrue( status.isSuccess(), "Fail to update " + repo + " repository index " + status ); } // let s w8 a few time for indexes TaskScheduleUtil.waitForAllTasksToStop(); } public static void updateIncrementalIndexes( String... repositories ) throws Exception { reindex( repositories, true ); } public RepositoryStatusResource getStatus( String repoId ) throws IOException { return getStatus( repoId, false ); } public RepositoryStatusResource getStatus( String repoId, boolean force ) throws IOException { String uri = SERVICE_PART + "/" + repoId + "/status"; if ( force ) { uri = uri + "?forceCheck=true"; } Response response = RequestFacade.sendMessage( uri, Method.GET ); Status status = response.getStatus(); Assert.assertTrue( status.isSuccess(), "Fail to getStatus for '" + repoId + "' repository" + status ); XStreamRepresentation representation = new XStreamRepresentation( this.xstream, response.getEntity().getText(), MediaType.APPLICATION_XML ); RepositoryStatusResourceResponse resourceResponse = (RepositoryStatusResourceResponse) representation.getPayload( new RepositoryStatusResourceResponse() ); return resourceResponse.getData(); } public void updateStatus( RepositoryStatusResource repoStatus ) throws IOException { String uriPart = SERVICE_PART + "/" + repoStatus.getId() + "/status"; XStreamRepresentation representation = new XStreamRepresentation( this.xstream, "", MediaType.APPLICATION_XML ); RepositoryStatusResourceResponse resourceResponse = new RepositoryStatusResourceResponse(); resourceResponse.setData( repoStatus ); representation.setPayload( resourceResponse ); Response response = RequestFacade.sendMessage( uriPart, Method.PUT, representation ); Status status = response.getStatus(); Assert.assertTrue( status.isSuccess(), "Fail to update '" + repoStatus.getId() + "' repository status " + status + "\nResponse:\n" + response.getEntity().getText() + "\nrepresentation:\n" + representation.getText() ); } /** * @param repoId * @return * @throws IOException * @deprecated This is half baked stuff */ public static ContentListResourceResponse downloadRepoIndexContent( String repoId ) throws IOException { String serviceURI = "service/local/repositories/" + repoId + "/index_content/"; Response response = RequestFacade.doGetRequest( serviceURI ); String responseText = response.getEntity().getText(); Status status = response.getStatus(); Assert.assertTrue( status.isSuccess(), responseText + status ); XStreamRepresentation re = new XStreamRepresentation( XStreamFactory.getXmlXStream(), responseText, MediaType.APPLICATION_XML ); ContentListResourceResponse resourceResponse = (ContentListResourceResponse) re.getPayload( new ContentListResourceResponse() ); return resourceResponse; } }