<bean class="jetbrains.buildServer.nuget.server.publish.PublishRunType"/>\r
\r
\r
- <bean class="jetbrains.buildServer.nuget.server.feed.reader.impl.FeedClient" destroy-method="dispose"/>\r
+ <bean class="jetbrains.buildServer.nuget.server.feed.reader.impl.FeedHttpClientHolder" destroy-method="dispose"/>\r
<bean class="jetbrains.buildServer.nuget.server.feed.reader.impl.NuGetFeedReaderImpl"/>\r
<bean class="jetbrains.buildServer.nuget.server.feed.reader.impl.FeedGetMethodFactory"/>\r
- <bean class="jetbrains.buildServer.nuget.server.feed.reader.impl.UrlResolver"/>\r
+ <bean class="jetbrains.buildServer.nuget.server.feed.reader.impl.PackagesFeedParserImpl"/>\r
+ <bean class="jetbrains.buildServer.nuget.server.feed.reader.impl.UrlResolverImpl"/>\r
\r
</beans>
\ No newline at end of file
\r
package jetbrains.buildServer.nuget.server.feed.reader.impl;\r
\r
-import jetbrains.buildServer.version.ServerVersionHolder;\r
import org.apache.http.client.HttpClient;\r
-import org.apache.http.impl.client.DefaultHttpClient;\r
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;\r
-import org.apache.http.params.HttpConnectionParams;\r
-import org.apache.http.params.HttpParams;\r
-import org.apache.http.params.HttpProtocolParams;\r
import org.jetbrains.annotations.NotNull;\r
\r
/**\r
* Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
- * Date: 11.08.11 16:24\r
+ * Date: 12.08.11 15:13\r
*/\r
-public class FeedClient {\r
- private final HttpClient myClient;\r
-\r
- public FeedClient() {\r
- myClient = new DefaultHttpClient(new ThreadSafeClientConnManager());\r
- final HttpParams params = myClient.getParams();\r
-\r
- HttpConnectionParams.setConnectionTimeout(params, 10000);\r
- HttpConnectionParams.setSoTimeout(params, 10000);\r
-\r
- final String serverVersion = ServerVersionHolder.getVersion().getDisplayVersion();\r
- HttpProtocolParams.setUserAgent(params, "JetBrains TeamCity " + serverVersion);\r
- }\r
-\r
+public interface FeedClient {\r
@NotNull\r
- public HttpClient getClient() {\r
- return myClient;\r
- }\r
-\r
- public void dispose() {\r
- myClient.getConnectionManager().shutdown();\r
- }\r
-\r
+ HttpClient getClient();\r
}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.feed.reader.impl;\r
+\r
+import jetbrains.buildServer.version.ServerVersionHolder;\r
+import org.apache.http.client.HttpClient;\r
+import org.apache.http.impl.client.DefaultHttpClient;\r
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;\r
+import org.apache.http.params.HttpConnectionParams;\r
+import org.apache.http.params.HttpParams;\r
+import org.apache.http.params.HttpProtocolParams;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+/**\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 11.08.11 16:24\r
+ */\r
+public class FeedHttpClientHolder implements FeedClient {\r
+ private final HttpClient myClient;\r
+\r
+ public FeedHttpClientHolder() {\r
+ myClient = new DefaultHttpClient(new ThreadSafeClientConnManager());\r
+ final HttpParams params = myClient.getParams();\r
+\r
+ HttpConnectionParams.setConnectionTimeout(params, 10000);\r
+ HttpConnectionParams.setSoTimeout(params, 10000);\r
+\r
+ final String serverVersion = ServerVersionHolder.getVersion().getDisplayVersion();\r
+ HttpProtocolParams.setUserAgent(params, "JetBrains TeamCity " + serverVersion);\r
+ }\r
+\r
+ @NotNull\r
+ public HttpClient getClient() {\r
+ return myClient;\r
+ }\r
+\r
+ public void dispose() {\r
+ myClient.getConnectionManager().shutdown();\r
+ }\r
+\r
+}\r
private final FeedGetMethodFactory myMethodFactory;\r
private final PackagesFeedParser myParser;\r
\r
- public NuGetFeedReaderImpl(FeedClient client, UrlResolver resolver, FeedGetMethodFactory methodFactory, PackagesFeedParser parser) {\r
+ public NuGetFeedReaderImpl(@NotNull final FeedClient client,\r
+ @NotNull final UrlResolver resolver,\r
+ @NotNull final FeedGetMethodFactory methodFactory,\r
+ @NotNull final PackagesFeedParser parser) {\r
myClient = client;\r
myResolver = resolver;\r
myMethodFactory = methodFactory;\r
\r
package jetbrains.buildServer.nuget.server.feed.reader.impl;\r
\r
-import com.intellij.openapi.diagnostic.Logger;\r
-import jetbrains.buildServer.nuget.common.PackageInfo;\r
import jetbrains.buildServer.nuget.server.feed.reader.FeedPackage;\r
-import jetbrains.buildServer.util.StringUtil;\r
import org.jdom.Element;\r
-import org.jdom.Namespace;\r
import org.jetbrains.annotations.NotNull;\r
\r
-import java.util.ArrayList;\r
import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.List;\r
\r
/**\r
* Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
- * Date: 12.08.11 13:42\r
+ * Date: 12.08.11 15:14\r
*/\r
-public class PackagesFeedParser {\r
- private static final Logger LOG = Logger.getInstance(PackagesFeedParser.class.getName());\r
-\r
- private static final Namespace atom = Namespace.getNamespace("http://www.w3.org/2005/Atom");\r
- private static final Namespace metadata = Namespace.getNamespace("http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");\r
- private static final Namespace services = Namespace.getNamespace("http://schemas.microsoft.com/ado/2007/08/dataservices");\r
-\r
- public Collection<FeedPackage> readPackages(@NotNull Element root) {\r
- final List<FeedPackage> result = new ArrayList<FeedPackage>();\r
-\r
- final List entries = root.getChildren("entry", atom);\r
- for (Object o : entries) {\r
- final Element entry = (Element) o;\r
- try {\r
- final FeedPackage e = parseOneEntry(entry);\r
- result.add(e);\r
- } catch (InvalidXmlException e) {\r
- LOG.debug("Failed to parse feed entry. " + e.getMessage());\r
- }\r
- }\r
- Collections.sort(result);\r
- return result;\r
- }\r
-\r
- @NotNull\r
- private FeedPackage parseOneEntry(Element entry) throws InvalidXmlException {\r
- final Element atomIdElement = getChild(entry, "id", atom);\r
- final String atomId = atomIdElement.getText();\r
-\r
- final String content = getChildAttribute(entry, "content", atom, "src");\r
- final Element props = getChild(entry, "properties", metadata);\r
-\r
- final String packageId = getChildText(props, "Id", services);\r
- final String version = getChildText(props, "Version", services);\r
- final String desription = getChildText(props, "Description", services);\r
- final String summary = getChildText(props, "Summary", services);\r
- final boolean isLatestVersion = "true".equalsIgnoreCase(getChildTextSafe(props, "IsLatestVersion", services));\r
-\r
- return new FeedPackage(\r
- atomId,\r
- new PackageInfo(packageId, version),\r
- isLatestVersion,\r
- StringUtil.isEmptyOrSpaces(desription) ? summary : desription,\r
- content);\r
- }\r
-\r
- @NotNull\r
- private String getChildTextSafe(@NotNull Element element,\r
- @NotNull String name,\r
- @NotNull Namespace ns) {\r
- try {\r
- return getChildText(element, name, ns);\r
- } catch (InvalidXmlException e) {\r
- return "";\r
- }\r
- }\r
-\r
- @NotNull\r
- private String getChildText(@NotNull Element element,\r
- @NotNull String name,\r
- @NotNull Namespace ns) throws InvalidXmlException {\r
- final Element data = getChild(element, name, ns);\r
- final String text = data.getText();\r
- if (StringUtil.isEmptyOrSpaces(text)) {\r
- throw new InvalidXmlException("Element " + name + " must have a content. ");\r
- }\r
- return text;\r
- }\r
-\r
- @NotNull\r
- private String getChildAttribute(@NotNull Element element,\r
- @NotNull String name,\r
- @NotNull Namespace ns,\r
- @NotNull String attribute) throws InvalidXmlException {\r
- final Element data = getChild(element, name, ns);\r
- final String text = data.getAttributeValue(attribute);\r
- if (StringUtil.isEmptyOrSpaces(text)) {\r
- throw new InvalidXmlException("Element " + name + " must have non-empty attribute " + attribute + ". ");\r
- }\r
- return text;\r
- }\r
-\r
- @NotNull\r
- private Element getChild(Element element, String name, Namespace ns) throws InvalidXmlException {\r
- final Element data = element.getChild(name, ns);\r
- if (data == null) {\r
- throw new InvalidXmlException("Element " + name + " was not found. ");\r
- }\r
- return data;\r
- }\r
-\r
- private static class InvalidXmlException extends Exception {\r
- private InvalidXmlException(String message) {\r
- super(message);\r
- }\r
- }\r
+public interface PackagesFeedParser {\r
+ Collection<FeedPackage> readPackages(@NotNull Element root);\r
}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.feed.reader.impl;\r
+\r
+import com.intellij.openapi.diagnostic.Logger;\r
+import jetbrains.buildServer.nuget.common.PackageInfo;\r
+import jetbrains.buildServer.nuget.server.feed.reader.FeedPackage;\r
+import jetbrains.buildServer.util.StringUtil;\r
+import org.jdom.Element;\r
+import org.jdom.Namespace;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 12.08.11 13:42\r
+ */\r
+public class PackagesFeedParserImpl implements PackagesFeedParser {\r
+ private static final Logger LOG = Logger.getInstance(PackagesFeedParserImpl.class.getName());\r
+\r
+ private static final Namespace atom = Namespace.getNamespace("http://www.w3.org/2005/Atom");\r
+ private static final Namespace metadata = Namespace.getNamespace("http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");\r
+ private static final Namespace services = Namespace.getNamespace("http://schemas.microsoft.com/ado/2007/08/dataservices");\r
+\r
+ public Collection<FeedPackage> readPackages(@NotNull Element root) {\r
+ final List<FeedPackage> result = new ArrayList<FeedPackage>();\r
+\r
+ final List entries = root.getChildren("entry", atom);\r
+ for (Object o : entries) {\r
+ final Element entry = (Element) o;\r
+ try {\r
+ final FeedPackage e = parseOneEntry(entry);\r
+ result.add(e);\r
+ } catch (InvalidXmlException e) {\r
+ LOG.debug("Failed to parse feed entry. " + e.getMessage());\r
+ }\r
+ }\r
+ Collections.sort(result);\r
+ return result;\r
+ }\r
+\r
+ @NotNull\r
+ private FeedPackage parseOneEntry(Element entry) throws InvalidXmlException {\r
+ final Element atomIdElement = getChild(entry, "id", atom);\r
+ final String atomId = atomIdElement.getText();\r
+\r
+ final String content = getChildAttribute(entry, "content", atom, "src");\r
+ final Element props = getChild(entry, "properties", metadata);\r
+\r
+ final String packageId = getChildText(props, "Id", services);\r
+ final String version = getChildText(props, "Version", services);\r
+ final String desription = getChildText(props, "Description", services);\r
+ final String summary = getChildText(props, "Summary", services);\r
+ final boolean isLatestVersion = "true".equalsIgnoreCase(getChildTextSafe(props, "IsLatestVersion", services));\r
+\r
+ return new FeedPackage(\r
+ atomId,\r
+ new PackageInfo(packageId, version),\r
+ isLatestVersion,\r
+ StringUtil.isEmptyOrSpaces(desription) ? summary : desription,\r
+ content);\r
+ }\r
+\r
+ @NotNull\r
+ private String getChildTextSafe(@NotNull Element element,\r
+ @NotNull String name,\r
+ @NotNull Namespace ns) {\r
+ try {\r
+ return getChildText(element, name, ns);\r
+ } catch (InvalidXmlException e) {\r
+ return "";\r
+ }\r
+ }\r
+\r
+ @NotNull\r
+ private String getChildText(@NotNull Element element,\r
+ @NotNull String name,\r
+ @NotNull Namespace ns) throws InvalidXmlException {\r
+ final Element data = getChild(element, name, ns);\r
+ final String text = data.getText();\r
+ if (StringUtil.isEmptyOrSpaces(text)) {\r
+ throw new InvalidXmlException("Element " + name + " must have a content. ");\r
+ }\r
+ return text;\r
+ }\r
+\r
+ @NotNull\r
+ private String getChildAttribute(@NotNull Element element,\r
+ @NotNull String name,\r
+ @NotNull Namespace ns,\r
+ @NotNull String attribute) throws InvalidXmlException {\r
+ final Element data = getChild(element, name, ns);\r
+ final String text = data.getAttributeValue(attribute);\r
+ if (StringUtil.isEmptyOrSpaces(text)) {\r
+ throw new InvalidXmlException("Element " + name + " must have non-empty attribute " + attribute + ". ");\r
+ }\r
+ return text;\r
+ }\r
+\r
+ @NotNull\r
+ private Element getChild(Element element, String name, Namespace ns) throws InvalidXmlException {\r
+ final Element data = element.getChild(name, ns);\r
+ if (data == null) {\r
+ throw new InvalidXmlException("Element " + name + " was not found. ");\r
+ }\r
+ return data;\r
+ }\r
+\r
+ private static class InvalidXmlException extends Exception {\r
+ private InvalidXmlException(String message) {\r
+ super(message);\r
+ }\r
+ }\r
+}\r
package jetbrains.buildServer.nuget.server.feed.reader.impl;\r
\r
import com.intellij.openapi.util.Pair;\r
-import org.apache.http.Header;\r
import org.apache.http.HttpResponse;\r
-import org.apache.http.HttpStatus;\r
-import org.apache.http.client.methods.HttpGet;\r
-import org.apache.http.client.params.ClientPNames;\r
import org.jetbrains.annotations.NotNull;\r
\r
import java.io.IOException;\r
\r
/**\r
* Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
- * Date: 12.08.11 10:24\r
+ * Date: 12.08.11 15:15\r
*/\r
-public class UrlResolver {\r
- private final FeedClient myClient;\r
- private final FeedGetMethodFactory myMethods;\r
-\r
- public UrlResolver(@NotNull final FeedClient client,\r
- @NotNull final FeedGetMethodFactory methods) {\r
- myClient = client;\r
- myMethods = methods;\r
- }\r
-\r
- /**\r
- * Generates GET request to a given URL.\r
- * If HTTP Status 3xx is returned, Location header is\r
- * used to generate next request unless non 3xx status\r
- * is returned\r
- * @param feedUrl url to ping and resolve\r
- * @return resolved URL and HttpResponse\r
- * @throws IOException if failed to communicate or non 3xx or 200 status returned\r
- */\r
+public interface UrlResolver {\r
@NotNull\r
- public Pair<String, HttpResponse> resolvePath(@NotNull String feedUrl) throws IOException {\r
- for(int _ = 100; _-->0;) {\r
- HttpGet ping = myMethods.createGet(feedUrl);\r
- ping.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);\r
-\r
- final HttpResponse execute = myClient.getClient().execute(ping);\r
- final int statusCode = execute.getStatusLine().getStatusCode();\r
- if (statusCode / 100 == 3) {\r
- final Header location = execute.getFirstHeader("Location");\r
- if (location != null) {\r
- feedUrl = location.getValue();\r
- continue;\r
- }\r
- }\r
-\r
- if (statusCode != HttpStatus.SC_OK) {\r
- throw new IOException("Failed to connect to " + feedUrl);\r
- }\r
- return Pair.create(feedUrl, execute);\r
- }\r
- throw new IOException("Failed to resolve redirects");\r
- }\r
-\r
+ Pair<String, HttpResponse> resolvePath(@NotNull String feedUrl) throws IOException;\r
}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.feed.reader.impl;\r
+\r
+import com.intellij.openapi.util.Pair;\r
+import org.apache.http.Header;\r
+import org.apache.http.HttpResponse;\r
+import org.apache.http.HttpStatus;\r
+import org.apache.http.client.methods.HttpGet;\r
+import org.apache.http.client.params.ClientPNames;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.io.IOException;\r
+\r
+/**\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 12.08.11 10:24\r
+ */\r
+public class UrlResolverImpl implements UrlResolver {\r
+ private final FeedClient myClient;\r
+ private final FeedGetMethodFactory myMethods;\r
+\r
+ public UrlResolverImpl(@NotNull final FeedClient client,\r
+ @NotNull final FeedGetMethodFactory methods) {\r
+ myClient = client;\r
+ myMethods = methods;\r
+ }\r
+\r
+ /**\r
+ * Generates GET request to a given URL.\r
+ * If HTTP Status 3xx is returned, Location header is\r
+ * used to generate next request unless non 3xx status\r
+ * is returned\r
+ * @param feedUrl url to ping and resolve\r
+ * @return resolved URL and HttpResponse\r
+ * @throws IOException if failed to communicate or non 3xx or 200 status returned\r
+ */\r
+ @NotNull\r
+ public Pair<String, HttpResponse> resolvePath(@NotNull String feedUrl) throws IOException {\r
+ for(int _ = 100; _-->0;) {\r
+ HttpGet ping = myMethods.createGet(feedUrl);\r
+ ping.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);\r
+\r
+ final HttpResponse execute = myClient.getClient().execute(ping);\r
+ final int statusCode = execute.getStatusLine().getStatusCode();\r
+ if (statusCode / 100 == 3) {\r
+ final Header location = execute.getFirstHeader("Location");\r
+ if (location != null) {\r
+ feedUrl = location.getValue();\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (statusCode != HttpStatus.SC_OK) {\r
+ throw new IOException("Failed to connect to " + feedUrl);\r
+ }\r
+ return Pair.create(feedUrl, execute);\r
+ }\r
+ throw new IOException("Failed to resolve redirects");\r
+ }\r
+\r
+}\r
*/\r
public class FeedReaderTest extends BaseTestCase {\r
private NuGetFeedReader myReader;\r
- private FeedClient myClient;\r
+ private FeedHttpClientHolder myClient;\r
\r
@BeforeMethod\r
@Override\r
protected void setUp() throws Exception {\r
super.setUp();\r
- myClient = new FeedClient();\r
+ myClient = new FeedHttpClientHolder();\r
final FeedGetMethodFactory methods = new FeedGetMethodFactory();\r
- myReader = new NuGetFeedReaderImpl(myClient, new UrlResolver(myClient, methods), methods, new PackagesFeedParser());\r
+ myReader = new NuGetFeedReaderImpl(myClient, new UrlResolverImpl(myClient, methods), methods, new PackagesFeedParserImpl());\r
}\r
\r
@AfterMethod\r
import jetbrains.buildServer.BaseTestCase;\r
import jetbrains.buildServer.nuget.server.feed.reader.FeedPackage;\r
import jetbrains.buildServer.nuget.server.feed.reader.impl.PackagesFeedParser;\r
+import jetbrains.buildServer.nuget.server.feed.reader.impl.PackagesFeedParserImpl;\r
import jetbrains.buildServer.nuget.tests.integration.Paths;\r
import jetbrains.buildServer.util.FileUtil;\r
import org.jdom.Element;\r
* Date: 12.08.11 13:44\r
*/\r
public class FeedPackagesParserTest extends BaseTestCase {\r
- private PackagesFeedParser myParser = new PackagesFeedParser();\r
+ private PackagesFeedParser myParser = new PackagesFeedParserImpl();\r
\r
@Test\r
public void test_ParseRealFeed() throws JDOMException, IOException {\r