SELECT t1.TID, t1.amt, RunningTotal = SUM(t2.amt)FROM dbo.Transactions AS t1
INNERJOIN dbo.Transactions AS t2
ON t1.TID >= t2.TID
GROUPBY t1.TID, t1.amt
ORDERBY t1.TID;
The reason this is slow? As the table gets larger, each incremental
row requires reading n-1 rows in the table. This is exponential and
bound for failures, timeouts, or just angry users.
Correlated subquery - do not do this either:
The subquery form is similarly painful for similarly painful reasons.
SELECT TID, amt, RunningTotal = amt +COALESCE((SELECT SUM(amt)FROM dbo.Transactions AS i
WHERE i.TID < o.TID),0)FROM dbo.Transactions AS o
ORDERBY TID;
Quirky update - do this at your own risk:
The "quirky update" method is more efficient than the above, but the
behavior is not documented, there are no guarantees about order, and the
behavior might work today but could break in the future. I'm including
this because it is a popular method and it is efficient, but that
doesn't mean I endorse it. The primary reason I even answered this
question instead of closing it as a duplicate is because the other question has a quirky update as the accepted answer.
DECLARE@t TABLE(
TID INT PRIMARYKEY,
amt INT,
RunningTotal INT
);DECLARE@RunningTotal INT =0;INSERT@t(TID, amt, RunningTotal)SELECT TID, amt, RunningTotal =0FROM dbo.Transactions
ORDERBY TID;UPDATE@t
SET@RunningTotal = RunningTotal =@RunningTotal + amt
FROM@t;SELECT TID, amt, RunningTotal
FROM@t
ORDERBY TID;
Recursive CTEs
This first one relies on TID to be contiguous, no gaps:
;WITH x AS(SELECT TID, amt, RunningTotal = amt
FROM dbo.Transactions
WHERE TID =1UNIONALLSELECT y.TID, y.amt, x.RunningTotal + y.amt
FROM x
INNERJOIN dbo.Transactions AS y
ON y.TID = x.TID +1)SELECT TID, amt, RunningTotal
FROM x
ORDERBY TID
OPTION(MAXRECURSION 10000);
If you can't rely on this, then you can use this variation, which simply builds a contiguous sequence using ROW_NUMBER():
;WITH y AS(SELECT TID, amt, rn = ROW_NUMBER()OVER(ORDERBY TID)FROM dbo.Transactions
), x AS(SELECT TID, rn, amt, rt = amt
FROM y
WHERE rn =1UNIONALLSELECT y.TID, y.rn, y.amt, x.rt + y.amt
FROM x INNERJOIN y
ON y.rn = x.rn +1)SELECT TID, amt, RunningTotal = rt
FROM x
ORDERBY x.rn
OPTION(MAXRECURSION 10000);
Depending on the size of the data (e.g. columns we don't know about),
you may find better overall performance by stuffing the relevant
columns only in a #temp table first, and processing against that instead
of the base table:
CREATETABLE#x
(
rn INT PRIMARYKEY,
TID INT,
amt INT
);INSERTINTO#x (rn, TID, amt)SELECT ROW_NUMBER()OVER(ORDERBY TID),
TID, amt
FROM dbo.Transactions;;WITH x AS(SELECT TID, rn, amt, rt = amt
FROM#x
WHERE rn =1UNIONALLSELECT y.TID, y.rn, y.amt, x.rt + y.amt
FROM x INNERJOIN#x AS y
ON y.rn = x.rn +1)SELECT TID, amt, RunningTotal = rt
FROM x
ORDERBY TID
OPTION(MAXRECURSION 10000);DROPTABLE#x;
Only the first CTE method will provide performance rivaling the
quirky update, but it makes a big assumption about the nature of the
data (no gaps). The other two methods will fall back and in those cases
you may as well use a cursor (if you can't use CLR and you're not yet on
SQL Server 2012).
Cursor
Everybody is told that cursors are evil, and that they should be
avoided at all costs, but this actually beats the performance of most
other supported methods, and is safer than the quirky update. The only
ones I prefer over the cursor solution are the 2012 and CLR methods
(below):
CREATETABLE#x
(
TID INT PRIMARYKEY,
amt INT,
rt INT
);INSERT#x(TID, amt)SELECT TID, amt
FROM dbo.Transactions
ORDERBY TID;DECLARE@rt INT,@tid INT,@amt INT;SET@rt =0;DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FORSELECT TID, amt FROM#x ORDERBY TID;OPEN c;FETCH c INTO@tid,@amt;WHILE@@FETCH_STATUS =0BEGINSET@rt =@rt +@amt;UPDATE#x SET rt =@rt WHERE TID =@tid;FETCH c INTO@tid,@amt;ENDCLOSE c;DEALLOCATE c;SELECT TID, amt, RunningTotal = rt
FROM#x
ORDERBY TID;DROPTABLE#x;
SQL Server 2012
In 2012, new window functions make this task a lot easier (and it performs better than all of the above methods as well):
Note that on larger data sets, you'll find that the above performs
much better than either of the following two options, since RANGE uses
an on-disk spool (and the default uses RANGE). However it is also
important to note that the behavior and results can differ, so be sure
they both return correct results before deciding between them based on
this difference.
For completeness, I'm offering a link to Pavel Pawlowski's CLR
method, which is by far the preferable method on versions prior to SQL
Server 2012 (but not 2000 obviously).
If you are on SQL Server 2012, the choice is obvious - use the new SUM() OVER() construct (with ROWS vs. RANGE).
For earlier versions, you'll want to compare the performance of the
alternative approaches on your schema, data and - taking
non-performance-related factors in mind - determine which approach is
right for you. It very well may be the CLR approach. Here are my
recommendations, in order of preference:
eclipse maven jetty plugin outofmemoryerror 이렇게 하면 될려나? 안해봤음..
<plugin><groupId>org.mortbay.jetty</groupId><artifactId>jetty-maven-plugin</artifactId><version>7.6.8.v20121106</version><executions><execution><id>start-jetty</id><!--Setthis to the appropriate phase:
pre-integration-test, or earlier test-compile--><phase>pre-integration-test</phase><goals><goal>jetty:run-forked</goal></goals></execution></executions><configuration><jvmArgs>-Xmx2048m-Xms1536m-XX:PermSize=128m-XX:MaxPermSize=256m</jvmArgs><scanIntervalSeconds>10</scanIntervalSeconds><webApp><contextPath>/</contextPath></webApp><contextHandlers><contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext"><war>../../api/target/main-api.war</war><contextPath>/test</contextPath></contextHandler></contextHandlers></configuration></plugin>
===================================== Warning:Dependency xpp3:xpp3:1.1.3.3 is ignored for debug as it may be conflicting with the internal version provided by Android. In case of problem, please repackage it with jarjar to change the class packages Warning:Dependency xpp3:xpp3:1.1.3.3 is ignored for release as it may be conflicting with the internal version provided by Android. In case of problem, please repackage it with jarjar to change the class packages ===================================== Error:Execution failed for task ‘:app:preDexDebug’. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘/usr/lib/jvm/java/bin/java” finished with non-zero exit value 1 =================================== java.lang.NoClassDefFoundError: org.simpleframework.xml.core.Persister =====================================
As Libraries stax-api e xpp3 entram em conflito com as classes do Android. As classes destes .jars parecem estar incluídas no Android. Para solucionar devemos implementar as dependências da seguinte maneira:
RESTful Web Services Example in Java with Jersey, Spring and MyBatis
Note: At the time of writing this post I was just starting with REST and Jersey so I suggest you have a look at Tutorial – REST API design and implementation in Java with Jersey and Spring instead.
My gained REST knowledge will be from now on reflected in this post,
which is already an “(r)evolution” regarding REST API design, REST best
practices used and backend architecture/implementation supporting the
REST API presented in the tutorial.
Looking to REST? In Java? There’s never time for that :), but if you are looking to use an “architectural
style consisting of a coordinated set of constraints applied to
components, connectors, and data elements, within a distributed hypermedia system” in Java,
then you have come to the right place, because in this post I will
present a simple RESTful API that maps REST calls to backend services
offering CRUD functionality.
Note: I will not focus too much on Representational state transfer (REST)
itself, because there are plenty of resources on the topic in the
internet, some of which I listed under Resources at the end of the post.
1. The example
1.1. Why?
My intention is to move some of the parts from Podcastpedia.org,
that are currently implemented in Spring MVC, to JavaScript-land and
for that I’ll need to use more backend REST web services. Of course I
could use Spring’s own REST implementation, as I currently do for the AJAX calls, but I wanted also to see how the “official” implementation looks like.
So, the best way to get to know the technology is build a prototype
with it. And that’s exactly what I did and what I will present in this
post. I’ve build a simple application that “manages” podcasts via a REST
API. It does CRUD operations on a single database table (Podcasts),
triggered via the REST web services API. Though fairly simple, the
example highlights the most common annotations you’ll need to build your
own REST API.
1.3. Architecture and technologies
1.3.1. Jersey
The architecture is straightforward: with any REST client you can call the application’s API exposed via Jersey RESTful Web Services in JAVA. The Jersey RESTful Web Services framework
is open source, production quality, framework for developing RESTful
Web Services in Java that provides support for JAX-RS APIs and serves as
a JAX-RS (JSR 311 & JSR 339) Reference Implementation.
1.3.2. Spring
I like glueing stuff together with Spring, and this example is no exception. You’ll find out how Jersey 2 integrates with Spring.
1.3.3. MyBatis
For the persistence layer, I chose Mybatis because I like it the most and it integrates fairly easy with Spring (see my post Spring MyBatis integration example
for more on that), but you are free to choose any framework and
technology you’re familiar with (e.g. JPA/Hibernate, Hibernate, JDBC
etc).
Everything gets packaged as a .war file and can be deployed on any web container – I used Tomcat and Jetty but, it could also be Glassfih, Weblogic, JBoss or WebSphere.
Note: The main focus in the post will be on the Jersey JAX-RS implementation, all the other technologies are viewed as enablers.
1.3.6. Technologies
Jersey 2.4
Spring 3.2
Maven 3
Tomcat 7
Jetty 9
MySql 5.6
1.3.7. Follow along
If you want to follow along, you find all you need on GitHub:
2. The coding
2.1. Configuration
2.1.1. Project dependencies
Among other things you need to have Jersey Spring extension in your
project’s classpath. You can easily add that with Maven by having the
following dependencies to the pom.xml file of the project:
dependency
groupIdglassfishjerseygroupId
artifactIdjerseyspring3artifactId
version2.4.1version
exclusions
exclusion
groupIdspringframeworkgroupId
artifactIdspringartifactId
exclusion
exclusion
groupIdspringframeworkgroupId
artifactIdspringartifactId
exclusion
exclusion
groupIdspringframeworkgroupId
artifactIdspringbeansartifactId
exclusion
exclusions
dependency
dependency
groupIdglassfishjerseymediagroupId
artifactIdjerseymediajacksonartifactId
version2.4.1version
dependency
Note: The jersey-spring3.jar, uses its own version
for Spring libraries, so to use the ones you want, you need to exclude
these libraries manually.
Notice the Jersey servlet configuration [lines 18-33]. The javax.ws.rs.core.Application class defines the components of the JAX-RS application. Because I extended the Application (ResourceConfig) class to provide the list of relevant root resource classes (getResources()) and singletons (getSingletons()), i.e. the JAX-RS application model, I needed to register it in my web application web.xml deployment descriptor using a Servlet or Servlet filter initialization parameter with a name of javax.ws.rs.Application.Check out the documentation for other possibilities.
The implementation of org.codingpedia.demo.rest.service.MyApplication looks like the following in the project:
* Registers the components to be used by the JAX-RS application
* @author ama
publicclassMyDemoApplicationextendsResourceConfig
* Register JAX-RS application components.
publicMyDemoApplication
registerRequestContextFilterclass
registerPodcastRestServiceclass
registerJacksonFeatureclass
The class registers the following components
org.glassfish.jersey.server.spring.scope.RequestContextFilter, which is a Spring filter that provides a bridge between JAX-RS and Spring request attributes
org.codingpedia.demo.rest.service.PodcastRestService, which is the service component that exposes the REST API via annotations, will be presented later in detail
org.glassfish.jersey.jackson.JacksonFeature, which is a feature that registers Jackson JSON providers – you need it for the application to understand JSON data
2.1.2.2. Spring application context configuration
The Spring application context configuration is located in the classpath under spring/applicationContext.xml:
Nothing special here, it just defines the beans that are needed throughout the demo application. The most important one is the podcastRestService which is actually the entry point class for our RESTful API, and will be thouroughly described in the next paragraphs.
2.2. The RESTful API
2.2.1. Resources
As mentioned earlier, the demo application manages podcasts, which represent the resources in our web API. Resources are the central concept in REST and are characterized by two main things:
each is referenced with a global identifier (e.g. a URI in HTTP).
has one or more representations, that they expose to the outer world
and can be manipulated with (we’ll be working mostly with JSON
representations in this example)
The podcast resources are represented in our application by the Podcast class:
Notice the @Path("/podcasts") before the class definition. The @Path annotation’s value is a relative URI path. In the example above, the Java class will be hosted at the URI path /podcasts. The PodcastDao interface is used to communicate with the database.
@POST – indicates that the method responds to HTTP POST requests
@Consumes({MediaType.APPLICATION_JSON}) – defines the media type, the method accepts, in this case "application/json"
@Produces({MediaType.TEXT_HTML}) – defines the media type) that the method can produce, in this case "text/html".
The response will be a html document, with a status of 201, indicating
to the caller that the request has been fulfilled and resulted in a new
resource being created.
@Transactional – Spring annotation, specifies that the method execution, should take place inside a transaction
2.2.2.1.2. Create multiple resources (“podcasts”) from JSON input
* A list of resources (here podcasts) provided in json format will be added
* to the database.
* @param podcasts
* @return
@POST@Path"list"
@ConsumesMediaTypeAPPLICATION_JSON
@Transactional
publicResponse createPodcasts<Podcast>podcasts
Podcast podcastpodcasts
podcastDaocreatePodcastpodcast
returnResponsestatusbuild
Annotations
@POST – indicates that the method responds to HTTP POST requests
@Path("/list") – identifies the URI path that the class method will serve requests for. Paths are relative. The combined path here will be "/podcasts/list", because as we have seen we have @Path annotation at the class level
@Consumes({MediaType.APPLICATION_JSON}) – defines the media type, the method accepts, in this case "application/json"
@Transactional– Spring annotation, specifies that the method execution, should take place inside a transaction
In this case the method returns a status of 204 (“No Content”),
suggesting that the server has fulfilled the request but does not need
to return an entity-body, and might want to return updated
metainformation.
2.2.2.1.3. Create a single resource (“podcast”) from form
* Adds a new resource (podcast) from "form" (at least title and feed elements are required
– defines the media type, the method accepts, in this case
"application/x-www-form-urlencoded"
@FormParam – present before the input parameters of the method, this
annotation binds the value(s) of a form parameter contained within a
request entity body to a resource method parameter. Values are URL
decoded unless this is disabled using the Encoded annotation
@Produces({MediaType.TEXT_HTML}) - defines the
media type) that the method can produce, in this case "text/html". The
response will be a html document, with a status of 201, indicating to
the caller that the request has been fulfilled and resulted in a new
resource being created.
@Transactional – Spring annotation, specifies that the method execution, should take place inside a transaction
2.2.2.2. READ
2.2.2.2.1. Read all resources
* Returns all resources (podcasts) from the database
@GET – indicates that the method responds to HTTP GET requests
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) – defines the media type) that the method can produce, in this case "application/json" or "application/xml"(you need the @XmlRootElement in front of the Podcast class to produce xml formatted response). The response will be a list of podcasts either in JSON or XML format.
returnResponsestatusentity"The podcast with the id "" does not exist"build
Annotations
@GET – indicates that the method responds to HTTP GET requests
@Path("{id}") – identifies the URI path that the class
method will serve requests for. The “id” value is an embedded variable
making an URI path template. It is used in combination with the @PathParam variable.
@PathParam("id") – binds the value of a URI template
parameter (“id”) to the resource method parameter. The value is URL
decoded unless this is di sabled using the @Encoded annotation. A default value can be specified using the @DefaultValue annotation.
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) – defines the media type) that the method can produce, in this case "application/json" or "application/xml"(you need the @XmlRootElement
in front of the Podcast class to produce the response in xml format).
The response will be a podcast either in JSON or XML format with the
“200 OK” status, or a message saying the podcast does not exit with a
“404 Not Found” status.
2.2.2.3. UPDATE
* Updates the attributes of the podcast received via JSON for the given @param id
* If the podcast does not exist yet in the database (verified by <strong>id</strong>) then
* the application will try to create a new podcast resource in the db
message"The podcast you provided has been added to the database"
status//Not acceptable
message"The information you provided is not sufficient to perform either an UPDATE or "
" an INSERTION of the new podcast resource <br/>"
" If you want to UPDATE please make sure you provide an existent <strong>id</strong> <br/>"
"
If you want to insert a new podcast please provide at least a
<strong>title</strong> and the
<strong>feed</strong> for the podcast resource"
returnResponsestatusstatusentitymessagebuild
Annotations
@PUT– indicates that the method responds to HTTP PUT requests
@Path("{id}") – identifies the URI path that the class
method will serve requests for. The “id” value is an embedded variable
making an URI path template. It is used in combination with the @PathParam variable.
@PathParam("id") – binds the value of a URI template
parameter (“id”) to the resource method parameter. The value is URL
decoded unless this is di sabled using the @Encoded annotation. A default value can be specified using the @DefaultValue annotation.
@Consumes({MediaType.APPLICATION_JSON}) – defines the media type, the method accepts, in this case "application/json"
@Produces({MediaType.TEXT_HTML}) – defines the media
type) that the method can produce, in this case “text/html”. The
response will be a html document containing different messages and stati
depending on what action has been taken
200 – OK, “podcast updated successfully “
201 – id given was not found in the db, so a new podcast resource has been created
406 – if id was not found and you haven’t provided enough
information for the creation of a new resource, the request is “Not
Acceptable”
2.2.2.4. DELETE
2.2.2.4.1. Delete all resources
@DELETE
@ProducesMediaTypeTEXT_HTML
publicResponse deletePodcasts
podcastDaodeletePodcasts
returnResponsestatusentity"All podcasts have been successfully removed"build
Annotations
@DELETE – indicates that the method responds to HTTP DELETE requests
@Produces({MediaType.TEXT_HTML}) – defines the media
type that the method can produce, in this case “text/html”. The response
will be a html document, with a status of 200, indicating to the caller
that the request has been fulfilled.
@Transactional – Spring annotation, specifies that the method execution, should take place inside a transaction
2.2.2.4.2. Delete one resource
@DELETE@Path"{id}"
@ProducesMediaTypeTEXT_HTML
@Transactional
publicResponse deletePodcastById@PathParam
podcastDaodeletePodcastById
returnResponsestatusbuild
returnResponsestatusentity"Podcast with the id "" is not present in the database"build
Annotations
@DELETE – indicates that the method responds to HTTP DELETE requests
@Path("{id}") – identifies the URI path that the class
method will serve requests for. The “id” value is an embedded variable
making an URI path template. It is used in combination with the @PathParam variable.
@PathParam("id") – binds the value of a URI template
parameter (“id”) to the resource method parameter. The value is URL
decoded unless this is di sabled using the @Encoded annotation. A default value can be specified using the @DefaultValue annotation.
@Produces({MediaType.TEXT_HTML}) – defines the media
type that the method can produce, in this case “text/html”. If the
podcast is deleted, that is found in the database, a 204 “No Content”
success status is returnred, otherwise an html document with the status
of 404 “Not found” is returned
@Transactional – Spring annotation, specifies that the method execution, should take place inside a transaction
3. Testing
3.1. Integration tests
To test the application I will use the Jersey Client and execute requests against a running Jetty server with the application deployed on it. For that I will use the Maven Failsafe Plugin.
3.1.1. Configuration
3.1.1.1 Jersey client dependency
To build a Jersey client the jersey-client jar is required in the classpath. With Maven you can add it as a dependency to the pom.xml file:
dependency
groupIdglassfishjerseygroupId
artifactIdjerseyclientartifactId
version2.4.1version
scopescope
dependency
3.1.1.2. Failsafe plugin
The Failsafe Plugin is used during the integration-test and verify
phases of the build lifecycle to execute the integration tests of the
application. The Failsafe Plugin will not fail the build during the
integration-test phase thus enabling the post-integration-test phase to
execute.
To use the Failsafe Plugin, you need to add the following configuration to your pom.xml
plugins
plugin
groupIdapachemavenpluginsgroupId
artifactIdmavenfailsafepluginartifactId
versionversion
executions
execution
integration
goals
integration
goals
execution
execution
verify
goals
verify
goals
execution
executions
plugin
plugins
3.1.1.2. Jetty Maven Plugin
As mentioned, the integration tests will be executed against a
running jetty server, that will be started only for the execution of the
tests. For that the following execution has to be configured in the jetty-maven-plugin configuration:
Note: In the pre-integration-test phase the Jetty server will be started, after stopping any running instance to free up the port, and in the post-integration-phase it will be stopped. The scanIntervalSeconds has to be set to 0, and daemon to true.
I am using JUnit as the testing framework. By default, the Failsafe
Plugin will automatically include all test classes with the following
wildcard patterns:
"**/IT*.java" – includes all of its subdirectories and all java filenames that start with “IT”.
"**/*IT.java" – includes all of its subdirectories and all java filenames that end with “IT”.
"**/*ITCase.java" – includes all of its subdirectories and all java filenames that end with “ITCase”.
I have created a single test class – RestDemoServiceIT – that will test the read (GET) methods, but the procedure should be the same for all the other:
print"Received podcast from database *************************** "
mapperwriterWithDefaultPrettyPrinter
writeValueAsStringpodcast
Note:
I had to register the JacksonFeature for the client too so that I
can marshall the podcast response in JSON format –
response.readEntity(Podcast.class)
I am testing against a running Jetty on port 8888 – I will show you in the next section how to start Jetty on a desired port
I am expecting a 200 status for my request
With the help org.codehaus.jackson.map.ObjectMapper I am displaying the JSON response nicely formatted
3.1.3. Running the integration tests
The Failsafe Plugin can be invoked by calling the verify phase of the build lifecycle.
verify
To start jetty on port 8888 you need to set the jetty.port property to 8888. In Eclipse I use the following configuration:
Run integration tests from Eclipse
3.2. Live tests
In the following video I will will show how to test the API application from Chrome with the help of DEV HTTP Client, which I highly recommend:
4. Summary
Well, that’s it. You’ve learned how to create a REST API with the
help of Jersey 2, how it integrates with Spring with the new
jersey-spring3 dependency and how to test the API with the Jersey Client
and from Chrome with the help of Dev HTTP Client.
If you’ve found some usefulnes in this post, I’d be very grateful if
you helped it spread by leaving a comment or sharing it on Twitter,
Google+ or Facebook. Thank you! Don’t forget also to check out Podcastpedia.org – you’ll find for sure interesting podcasts and episodes. We are grateful for your support.
root@dns1 ~]# tail /var/log/maillog Mar 30 02:21:29 dns1 dovecot: pop3-login: Login: user=<scbyun>, method=PLAIN, rip=192.168.43.237, lip=192.168.43.8 Mar 30 02:21:29 dns1 dovecot: POP3(scbyun): Disconnected: Logged out top=0/0, retr=0/0, del=0/1, size=579 Mar 30 02:22:53 dns1 sendmail[2463]: p2THMouO002463: ruleset=check_rcpt, arg1=<anti1346@gmail.com>, relay=[192.168.43.237], reject=550 5.7.1 <anti1346@gmail.com>... Relaying denied. IP name lookup failed [192.168.43.237]
[해결 방법]
[root@dns1 ~]# cat /etc/mail/access # Check the /usr/share/doc/sendmail/README.cf file for a description # of the format of this file. (search for access_db in that file) # The /usr/share/doc/sendmail/README.cf is part of the sendmail-doc # package. # # by default we allow relaying from localhost... Connect:localhost.localdomain RELAY Connect:localhost RELAY Connect:127.0.0.1 RELAY
vi /etc/mail/access
Connect:192.168.43 RELAY <=== mail 서버에 접속할 IP 추가
[root@dns1 ~]#
[root@dns1 ~]# /usr/sbin/makemap hash /etc/mail/access < /etc/mail/access (sendmail 재시작 없이 바로 적용됨)
guzzle/guzzle suggests installing guzzlehttp/guzzle (Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated.)