├── .gitignore
├── README.md
├── doozerd-0.8
├── linux-386
│ ├── doozer
│ └── doozerd
└── osx-386
│ ├── doozer
│ └── doozerd
├── project
├── build.properties
└── build
│ └── FlangeProject.scala
├── src
├── main
│ ├── java
│ │ └── doozer
│ │ │ └── DoozerMsg.java
│ ├── protobuf
│ │ └── doozer-msg.proto
│ ├── resources
│ │ └── akka.conf
│ └── scala
│ │ └── com
│ │ └── force
│ │ └── doozer
│ │ └── flange
│ │ ├── DoozerClient.scala
│ │ └── Messages.scala
└── test
│ └── scala
│ └── com
│ └── force
│ └── doozer
│ └── flange
│ ├── ClientSpec.scala
│ ├── ConnectionSpec.scala
│ ├── FailoverSpec.scala
│ ├── URISpec.scala
│ └── Waiting.scala
├── startDoozer.sh
└── stopDoozer.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *#
3 | src_managed
4 | activemq-data
5 | project/plugins/project
6 | project/boot/*
7 | */project/build/target
8 | */project/boot
9 | lib_managed
10 | etags
11 | tags
12 | TAGS
13 | akka.tmproj
14 | reports
15 | dist
16 | build
17 | target
18 | deploy/*.jar
19 | data
20 | out
21 | logs
22 | .#*
23 | .codefellow
24 | storage
25 | .codefellow
26 | .ensime
27 | _dump
28 | .manager
29 | manifest.mf
30 | semantic.cache
31 | tm*.log
32 | tm*.lck
33 | tm.out
34 | *.tm.epoch
35 | .DS_Store
36 | *.iws
37 | *.ipr
38 | *.iml
39 | run-codefellow
40 | .project
41 | .settings
42 | .classpath
43 | .idea
44 | .scala_dependencies
45 | multiverse.log
46 | .eprj
47 | .*.swp
48 | akka-tutorials/akka-tutorial-pi-sbt/project/boot/
49 | doozer-*/dooz.log
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flange: Scala client For Doozer
2 |
3 | ## Build and test
4 |
5 | ./startDoozer.sh
6 | sbt test
7 | ./stopDoozer.sh
8 |
9 | ## Basic Usage (explicit types for clarity)
10 | ./startDoozer.sh
11 | sbt console
12 |
13 | import com.force.doozer.flange.Flange
14 | import com.force.doozer.flange.{GetResponse,SetResponse,ErrorResponse,WatchNotification,WatchResponse}
15 |
16 | val client = new Flange("doozer:?ca=localhost:8046&ca=localhost:8047&ca=localhost:8048")
17 |
18 | //Set returns an Left(ErrorResponse(_,_)) if there is a failure
19 | val set:Either[ErrorResponse,SetResponse] = client.set("/foo", "bar".getBytes(), 0L)
20 |
21 | //Set succeeds or throws an exception
22 | val set2:SetResponse = client.set_!("/foofoo", "bar".getBytes(), 0L)
23 |
24 | //Get returns an Left(ErrorResponse(_,_)) if there is a failure
25 | val get:Either[ErrorResponse,GetResponse] = client.get("/foo")
26 | //Get succeeds or exception is thrown
27 | val get2:GetResponse = client.get_!("/foofoo")
28 | //Watch succeeds or exception is thrown
29 | val watch:WatchResponse = client.watch_!("/foofoo", get2.cas){
30 | notification:WatchNotification => System.out.println("/foofoo changed to "+new String(notification.value))
31 | }
32 | client.set_!("/foofoo", "newbar".getBytes(), get2.cas)
33 | //Should print notification of change
34 |
35 |
36 | ##Failover
37 |
38 | The Flange client will by default will failover to each of the doozer servers specified in the doozerURI when an operation fails. The failing operation
39 | is transparently retried. Once all of the doozer servers have failed the client is dead.
40 |
41 | This behavior is pluggable. You simply need to supply a function of List[String] => Iterable[String] when constructing a Flange instance
42 | that will be passed the list of doozerd hosts parsed from the doozer URI.
43 |
44 | The Flange companion object defines 2 of these functions, eachDoozerOnceStrategy and retryForeverStrategy. The default is eachDoozerOnceStrategy
45 |
46 | To use the retryForeverStrategy
47 |
48 | import com.force.doozer.flange.Flange
49 | import com.force.doozer.flange.Flange._
50 |
51 | val doozerUri = ...
52 | val flange = new Flange(doozerUri, retryForeverStrategy)
53 |
54 |
55 | To use your own
56 |
57 | import com.force.doozer.flange.Flange
58 |
59 | val funk: List[String]=>Iterable[String] = {doozerds:List[String]=>...}
60 | val doozerUri = ...
61 | val flange = new Flange(doozerUri, funk)
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/doozerd-0.8/linux-386/doozer:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sclasen/flange/a49aeebdc59554a82f5bf53471fe480958f782fe/doozerd-0.8/linux-386/doozer
--------------------------------------------------------------------------------
/doozerd-0.8/linux-386/doozerd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sclasen/flange/a49aeebdc59554a82f5bf53471fe480958f782fe/doozerd-0.8/linux-386/doozerd
--------------------------------------------------------------------------------
/doozerd-0.8/osx-386/doozer:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sclasen/flange/a49aeebdc59554a82f5bf53471fe480958f782fe/doozerd-0.8/osx-386/doozer
--------------------------------------------------------------------------------
/doozerd-0.8/osx-386/doozerd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sclasen/flange/a49aeebdc59554a82f5bf53471fe480958f782fe/doozerd-0.8/osx-386/doozerd
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | #Project properties
2 | #Thu Apr 21 15:10:58 PDT 2011
3 | project.organization=com.force.doozer
4 | project.name=flange
5 | sbt.version=0.7.7
6 | project.version=1.0
7 | build.scala.versions=2.9.0
8 | project.initialize=false
9 |
--------------------------------------------------------------------------------
/project/build/FlangeProject.scala:
--------------------------------------------------------------------------------
1 | import sbt._
2 |
3 | class FlangeProject(info: ProjectInfo) extends DefaultProject(info) {
4 |
5 |
6 | object Repositories {
7 | lazy val AkkaRepo = MavenRepository("Akka Repository", "http://akka.io/repository")
8 | lazy val ScalaToolsRepo = MavenRepository("Scala-Tools Repo", "http://scala-tools.org/repo-releases")
9 | lazy val ScalaToolsSnapshotRepo = MavenRepository("Scala-Tools Snapshot Repo", "http://scala-tools.org/repo-snapshots")
10 | lazy val CodehausRepo = MavenRepository("Codehaus Repo", "http://repository.codehaus.org")
11 | lazy val LocalMavenRepo = MavenRepository("Local Maven Repo", (Path.userHome / ".m2" / "repository").asURL.toString)
12 | lazy val GuiceyFruitRepo = MavenRepository("GuiceyFruit Repo", "http://guiceyfruit.googlecode.com/svn/repo/releases/")
13 | lazy val JBossRepo = MavenRepository("JBoss Repo", "http://repository.jboss.org/nexus/content/groups/public/")
14 | lazy val JavaNetRepo = MavenRepository("java.net Repo", "http://download.java.net/maven/2")
15 | lazy val SonatypeSnapshotRepo = MavenRepository("Sonatype OSS Repo", "http://oss.sonatype.org/content/repositories/releases")
16 | lazy val SunJDMKRepo = MavenRepository("Sun JDMK Repo", "http://wp5.e-taxonomy.eu/cdmlib/mavenrepo")
17 | lazy val ClojarsRepo = MavenRepository("Clojars Repo", "http://clojars.org/repo")
18 | lazy val ScalaToolsRelRepo = MavenRepository("Scala Tools Releases Repo", "http://scala-tools.org/repo-releases")
19 | lazy val ForceRelRepo = MavenRepository("Force releases", "http://repo.t.salesforce.com/archiva/repository/releases")
20 | lazy val ForceSnaplRepo = MavenRepository("Force snapshots", "http://repo.t.salesforce.com/archiva/repository/snapshots")
21 | lazy val javanetRepo = MavenRepository("javanetrepo", "http://download.java.net/maven/2/")
22 | }
23 |
24 | import Repositories._
25 |
26 | lazy val nettyModuleConfig = ModuleConfiguration("org.jboss.netty", JBossRepo)
27 | lazy val akkaoduleConfig = ModuleConfiguration("se.scalablesolutions.akka", AkkaRepo)
28 | lazy val scalaTestModuleConfig = ModuleConfiguration("org.scalatest", ScalaToolsSnapshots)
29 | val localMavenRepo = LocalMavenRepo
30 |
31 | // Second exception, also fast! ;-)
32 |
33 | // -------------------------------------------------------------------------------------------------------------------
34 | // Versions
35 | // -------------------------------------------------------------------------------------------------------------------
36 |
37 | lazy val AKKA_VERSION = "1.1"
38 | lazy val CAMEL_VERSION = "2.7.0"
39 | lazy val SCALATEST_VERSION = "1.4-SNAPSHOT"
40 | lazy val SLF4J_VERSION = "1.6.0"
41 |
42 | // -------------------------------------------------------------------------------------------------------------------
43 | // Dependencies
44 | // -------------------------------------------------------------------------------------------------------------------
45 |
46 | object Dependencies {
47 |
48 | // Compile
49 | lazy val akka_actor = "se.scalablesolutions.akka" % "akka-actor" % AKKA_VERSION % "compile" withSources ()
50 | //ApacheV2
51 | lazy val akka_slf4j = "se.scalablesolutions.akka" % "akka-slf4j" % AKKA_VERSION % "compile"
52 | //ApacheV2
53 | lazy val camel_netty = "org.apache.camel" % "camel-netty" % CAMEL_VERSION % "compile" withSources ()
54 | //ApacheV2
55 | lazy val netty = "org.jboss.netty" % "netty" % "3.2.3.Final" % "compile" withSources ()
56 | //ApacheV2
57 | lazy val protobuf = "com.google.protobuf" % "protobuf-java" % "2.4.0a" withSources ()
58 | //New BSD
59 | lazy val slf4_api = "org.slf4j" % "slf4j-api" % SLF4J_VERSION % "compile"
60 | lazy val slf4_jcl = "org.slf4j" % "jcl-over-slf4j" % SLF4J_VERSION % "compile"
61 | lazy val slf4_jul = "org.slf4j" % "jul-to-slf4j" % SLF4J_VERSION % "compile"
62 | lazy val slf4_log4j = "org.slf4j" % "log4j-over-slf4j" % SLF4J_VERSION % "compile"
63 | // MIT
64 | // Test
65 | lazy val scalatest = "org.scalatest" % "scalatest" % SCALATEST_VERSION % "test"
66 | //ApacheV2
67 | lazy val logback = "ch.qos.logback" % "logback-classic" % "0.9.28" % "compile"
68 |
69 | }
70 |
71 |
72 | override def ivyXML =
73 |
74 |
75 |
76 |
77 | val protobuf = Dependencies.protobuf
78 | val akka_actor = Dependencies.akka_actor
79 | val netty = Dependencies.netty
80 | val akka_slf4j = Dependencies.akka_slf4j
81 | val slf4j_api = Dependencies.slf4_api
82 | val logback = Dependencies.logback
83 | val scalatest = Dependencies.scalatest
84 |
85 |
86 | }
--------------------------------------------------------------------------------
/src/main/java/doozer/DoozerMsg.java:
--------------------------------------------------------------------------------
1 | // Generated by the protocol buffer compiler. DO NOT EDIT!
2 | // source: doozer-msg.proto
3 |
4 | package doozer;
5 |
6 | public final class DoozerMsg {
7 | private DoozerMsg() {}
8 | public static void registerAllExtensions(
9 | com.google.protobuf.ExtensionRegistry registry) {
10 | }
11 | public interface RequestOrBuilder
12 | extends com.google.protobuf.MessageOrBuilder {
13 |
14 | // optional int32 tag = 1;
15 | boolean hasTag();
16 | int getTag();
17 |
18 | // optional .doozer.Request.Verb verb = 2;
19 | boolean hasVerb();
20 | doozer.DoozerMsg.Request.Verb getVerb();
21 |
22 | // optional string path = 4;
23 | boolean hasPath();
24 | String getPath();
25 |
26 | // optional bytes value = 5;
27 | boolean hasValue();
28 | com.google.protobuf.ByteString getValue();
29 |
30 | // optional int32 other_tag = 6;
31 | boolean hasOtherTag();
32 | int getOtherTag();
33 |
34 | // optional int32 offset = 7;
35 | boolean hasOffset();
36 | int getOffset();
37 |
38 | // optional int64 rev = 9;
39 | boolean hasRev();
40 | long getRev();
41 | }
42 | public static final class Request extends
43 | com.google.protobuf.GeneratedMessage
44 | implements RequestOrBuilder {
45 | // Use Request.newBuilder() to construct.
46 | private Request(Builder builder) {
47 | super(builder);
48 | }
49 | private Request(boolean noInit) {}
50 |
51 | private static final Request defaultInstance;
52 | public static Request getDefaultInstance() {
53 | return defaultInstance;
54 | }
55 |
56 | public Request getDefaultInstanceForType() {
57 | return defaultInstance;
58 | }
59 |
60 | public static final com.google.protobuf.Descriptors.Descriptor
61 | getDescriptor() {
62 | return doozer.DoozerMsg.internal_static_doozer_Request_descriptor;
63 | }
64 |
65 | protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
66 | internalGetFieldAccessorTable() {
67 | return doozer.DoozerMsg.internal_static_doozer_Request_fieldAccessorTable;
68 | }
69 |
70 | public enum Verb
71 | implements com.google.protobuf.ProtocolMessageEnum {
72 | GET(0, 1),
73 | SET(1, 2),
74 | DEL(2, 3),
75 | REV(3, 5),
76 | WAIT(4, 6),
77 | NOP(5, 7),
78 | WALK(6, 9),
79 | GETDIR(7, 14),
80 | STAT(8, 16),
81 | ACCESS(9, 99),
82 | ;
83 |
84 | public static final int GET_VALUE = 1;
85 | public static final int SET_VALUE = 2;
86 | public static final int DEL_VALUE = 3;
87 | public static final int REV_VALUE = 5;
88 | public static final int WAIT_VALUE = 6;
89 | public static final int NOP_VALUE = 7;
90 | public static final int WALK_VALUE = 9;
91 | public static final int GETDIR_VALUE = 14;
92 | public static final int STAT_VALUE = 16;
93 | public static final int ACCESS_VALUE = 99;
94 |
95 |
96 | public final int getNumber() { return value; }
97 |
98 | public static Verb valueOf(int value) {
99 | switch (value) {
100 | case 1: return GET;
101 | case 2: return SET;
102 | case 3: return DEL;
103 | case 5: return REV;
104 | case 6: return WAIT;
105 | case 7: return NOP;
106 | case 9: return WALK;
107 | case 14: return GETDIR;
108 | case 16: return STAT;
109 | case 99: return ACCESS;
110 | default: return null;
111 | }
112 | }
113 |
114 | public static com.google.protobuf.Internal.EnumLiteMap
115 | internalGetValueMap() {
116 | return internalValueMap;
117 | }
118 | private static com.google.protobuf.Internal.EnumLiteMap
119 | internalValueMap =
120 | new com.google.protobuf.Internal.EnumLiteMap() {
121 | public Verb findValueByNumber(int number) {
122 | return Verb.valueOf(number);
123 | }
124 | };
125 |
126 | public final com.google.protobuf.Descriptors.EnumValueDescriptor
127 | getValueDescriptor() {
128 | return getDescriptor().getValues().get(index);
129 | }
130 | public final com.google.protobuf.Descriptors.EnumDescriptor
131 | getDescriptorForType() {
132 | return getDescriptor();
133 | }
134 | public static final com.google.protobuf.Descriptors.EnumDescriptor
135 | getDescriptor() {
136 | return doozer.DoozerMsg.Request.getDescriptor().getEnumTypes().get(0);
137 | }
138 |
139 | private static final Verb[] VALUES = {
140 | GET, SET, DEL, REV, WAIT, NOP, WALK, GETDIR, STAT, ACCESS,
141 | };
142 |
143 | public static Verb valueOf(
144 | com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
145 | if (desc.getType() != getDescriptor()) {
146 | throw new java.lang.IllegalArgumentException(
147 | "EnumValueDescriptor is not for this type.");
148 | }
149 | return VALUES[desc.getIndex()];
150 | }
151 |
152 | private final int index;
153 | private final int value;
154 |
155 | private Verb(int index, int value) {
156 | this.index = index;
157 | this.value = value;
158 | }
159 |
160 | // @@protoc_insertion_point(enum_scope:doozer.Request.Verb)
161 | }
162 |
163 | private int bitField0_;
164 | // optional int32 tag = 1;
165 | public static final int TAG_FIELD_NUMBER = 1;
166 | private int tag_;
167 | public boolean hasTag() {
168 | return ((bitField0_ & 0x00000001) == 0x00000001);
169 | }
170 | public int getTag() {
171 | return tag_;
172 | }
173 |
174 | // optional .doozer.Request.Verb verb = 2;
175 | public static final int VERB_FIELD_NUMBER = 2;
176 | private doozer.DoozerMsg.Request.Verb verb_;
177 | public boolean hasVerb() {
178 | return ((bitField0_ & 0x00000002) == 0x00000002);
179 | }
180 | public doozer.DoozerMsg.Request.Verb getVerb() {
181 | return verb_;
182 | }
183 |
184 | // optional string path = 4;
185 | public static final int PATH_FIELD_NUMBER = 4;
186 | private Object path_;
187 | public boolean hasPath() {
188 | return ((bitField0_ & 0x00000004) == 0x00000004);
189 | }
190 | public String getPath() {
191 | Object ref = path_;
192 | if (ref instanceof String) {
193 | return (String) ref;
194 | } else {
195 | com.google.protobuf.ByteString bs =
196 | (com.google.protobuf.ByteString) ref;
197 | String s = bs.toStringUtf8();
198 | if (com.google.protobuf.Internal.isValidUtf8(bs)) {
199 | path_ = s;
200 | }
201 | return s;
202 | }
203 | }
204 | private com.google.protobuf.ByteString getPathBytes() {
205 | Object ref = path_;
206 | if (ref instanceof String) {
207 | com.google.protobuf.ByteString b =
208 | com.google.protobuf.ByteString.copyFromUtf8((String) ref);
209 | path_ = b;
210 | return b;
211 | } else {
212 | return (com.google.protobuf.ByteString) ref;
213 | }
214 | }
215 |
216 | // optional bytes value = 5;
217 | public static final int VALUE_FIELD_NUMBER = 5;
218 | private com.google.protobuf.ByteString value_;
219 | public boolean hasValue() {
220 | return ((bitField0_ & 0x00000008) == 0x00000008);
221 | }
222 | public com.google.protobuf.ByteString getValue() {
223 | return value_;
224 | }
225 |
226 | // optional int32 other_tag = 6;
227 | public static final int OTHER_TAG_FIELD_NUMBER = 6;
228 | private int otherTag_;
229 | public boolean hasOtherTag() {
230 | return ((bitField0_ & 0x00000010) == 0x00000010);
231 | }
232 | public int getOtherTag() {
233 | return otherTag_;
234 | }
235 |
236 | // optional int32 offset = 7;
237 | public static final int OFFSET_FIELD_NUMBER = 7;
238 | private int offset_;
239 | public boolean hasOffset() {
240 | return ((bitField0_ & 0x00000020) == 0x00000020);
241 | }
242 | public int getOffset() {
243 | return offset_;
244 | }
245 |
246 | // optional int64 rev = 9;
247 | public static final int REV_FIELD_NUMBER = 9;
248 | private long rev_;
249 | public boolean hasRev() {
250 | return ((bitField0_ & 0x00000040) == 0x00000040);
251 | }
252 | public long getRev() {
253 | return rev_;
254 | }
255 |
256 | private void initFields() {
257 | tag_ = 0;
258 | verb_ = doozer.DoozerMsg.Request.Verb.GET;
259 | path_ = "";
260 | value_ = com.google.protobuf.ByteString.EMPTY;
261 | otherTag_ = 0;
262 | offset_ = 0;
263 | rev_ = 0L;
264 | }
265 | private byte memoizedIsInitialized = -1;
266 | public final boolean isInitialized() {
267 | byte isInitialized = memoizedIsInitialized;
268 | if (isInitialized != -1) return isInitialized == 1;
269 |
270 | memoizedIsInitialized = 1;
271 | return true;
272 | }
273 |
274 | public void writeTo(com.google.protobuf.CodedOutputStream output)
275 | throws java.io.IOException {
276 | getSerializedSize();
277 | if (((bitField0_ & 0x00000001) == 0x00000001)) {
278 | output.writeInt32(1, tag_);
279 | }
280 | if (((bitField0_ & 0x00000002) == 0x00000002)) {
281 | output.writeEnum(2, verb_.getNumber());
282 | }
283 | if (((bitField0_ & 0x00000004) == 0x00000004)) {
284 | output.writeBytes(4, getPathBytes());
285 | }
286 | if (((bitField0_ & 0x00000008) == 0x00000008)) {
287 | output.writeBytes(5, value_);
288 | }
289 | if (((bitField0_ & 0x00000010) == 0x00000010)) {
290 | output.writeInt32(6, otherTag_);
291 | }
292 | if (((bitField0_ & 0x00000020) == 0x00000020)) {
293 | output.writeInt32(7, offset_);
294 | }
295 | if (((bitField0_ & 0x00000040) == 0x00000040)) {
296 | output.writeInt64(9, rev_);
297 | }
298 | getUnknownFields().writeTo(output);
299 | }
300 |
301 | private int memoizedSerializedSize = -1;
302 | public int getSerializedSize() {
303 | int size = memoizedSerializedSize;
304 | if (size != -1) return size;
305 |
306 | size = 0;
307 | if (((bitField0_ & 0x00000001) == 0x00000001)) {
308 | size += com.google.protobuf.CodedOutputStream
309 | .computeInt32Size(1, tag_);
310 | }
311 | if (((bitField0_ & 0x00000002) == 0x00000002)) {
312 | size += com.google.protobuf.CodedOutputStream
313 | .computeEnumSize(2, verb_.getNumber());
314 | }
315 | if (((bitField0_ & 0x00000004) == 0x00000004)) {
316 | size += com.google.protobuf.CodedOutputStream
317 | .computeBytesSize(4, getPathBytes());
318 | }
319 | if (((bitField0_ & 0x00000008) == 0x00000008)) {
320 | size += com.google.protobuf.CodedOutputStream
321 | .computeBytesSize(5, value_);
322 | }
323 | if (((bitField0_ & 0x00000010) == 0x00000010)) {
324 | size += com.google.protobuf.CodedOutputStream
325 | .computeInt32Size(6, otherTag_);
326 | }
327 | if (((bitField0_ & 0x00000020) == 0x00000020)) {
328 | size += com.google.protobuf.CodedOutputStream
329 | .computeInt32Size(7, offset_);
330 | }
331 | if (((bitField0_ & 0x00000040) == 0x00000040)) {
332 | size += com.google.protobuf.CodedOutputStream
333 | .computeInt64Size(9, rev_);
334 | }
335 | size += getUnknownFields().getSerializedSize();
336 | memoizedSerializedSize = size;
337 | return size;
338 | }
339 |
340 | @java.lang.Override
341 | protected Object writeReplace() throws java.io.ObjectStreamException {
342 | return super.writeReplace();
343 | }
344 |
345 | public static doozer.DoozerMsg.Request parseFrom(
346 | com.google.protobuf.ByteString data)
347 | throws com.google.protobuf.InvalidProtocolBufferException {
348 | return newBuilder().mergeFrom(data).buildParsed();
349 | }
350 | public static doozer.DoozerMsg.Request parseFrom(
351 | com.google.protobuf.ByteString data,
352 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
353 | throws com.google.protobuf.InvalidProtocolBufferException {
354 | return newBuilder().mergeFrom(data, extensionRegistry)
355 | .buildParsed();
356 | }
357 | public static doozer.DoozerMsg.Request parseFrom(byte[] data)
358 | throws com.google.protobuf.InvalidProtocolBufferException {
359 | return newBuilder().mergeFrom(data).buildParsed();
360 | }
361 | public static doozer.DoozerMsg.Request parseFrom(
362 | byte[] data,
363 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
364 | throws com.google.protobuf.InvalidProtocolBufferException {
365 | return newBuilder().mergeFrom(data, extensionRegistry)
366 | .buildParsed();
367 | }
368 | public static doozer.DoozerMsg.Request parseFrom(java.io.InputStream input)
369 | throws java.io.IOException {
370 | return newBuilder().mergeFrom(input).buildParsed();
371 | }
372 | public static doozer.DoozerMsg.Request parseFrom(
373 | java.io.InputStream input,
374 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
375 | throws java.io.IOException {
376 | return newBuilder().mergeFrom(input, extensionRegistry)
377 | .buildParsed();
378 | }
379 | public static doozer.DoozerMsg.Request parseDelimitedFrom(java.io.InputStream input)
380 | throws java.io.IOException {
381 | Builder builder = newBuilder();
382 | if (builder.mergeDelimitedFrom(input)) {
383 | return builder.buildParsed();
384 | } else {
385 | return null;
386 | }
387 | }
388 | public static doozer.DoozerMsg.Request parseDelimitedFrom(
389 | java.io.InputStream input,
390 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
391 | throws java.io.IOException {
392 | Builder builder = newBuilder();
393 | if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
394 | return builder.buildParsed();
395 | } else {
396 | return null;
397 | }
398 | }
399 | public static doozer.DoozerMsg.Request parseFrom(
400 | com.google.protobuf.CodedInputStream input)
401 | throws java.io.IOException {
402 | return newBuilder().mergeFrom(input).buildParsed();
403 | }
404 | public static doozer.DoozerMsg.Request parseFrom(
405 | com.google.protobuf.CodedInputStream input,
406 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
407 | throws java.io.IOException {
408 | return newBuilder().mergeFrom(input, extensionRegistry)
409 | .buildParsed();
410 | }
411 |
412 | public static Builder newBuilder() { return Builder.create(); }
413 | public Builder newBuilderForType() { return newBuilder(); }
414 | public static Builder newBuilder(doozer.DoozerMsg.Request prototype) {
415 | return newBuilder().mergeFrom(prototype);
416 | }
417 | public Builder toBuilder() { return newBuilder(this); }
418 |
419 | @java.lang.Override
420 | protected Builder newBuilderForType(
421 | com.google.protobuf.GeneratedMessage.BuilderParent parent) {
422 | Builder builder = new Builder(parent);
423 | return builder;
424 | }
425 | public static final class Builder extends
426 | com.google.protobuf.GeneratedMessage.Builder
427 | implements doozer.DoozerMsg.RequestOrBuilder {
428 | public static final com.google.protobuf.Descriptors.Descriptor
429 | getDescriptor() {
430 | return doozer.DoozerMsg.internal_static_doozer_Request_descriptor;
431 | }
432 |
433 | protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
434 | internalGetFieldAccessorTable() {
435 | return doozer.DoozerMsg.internal_static_doozer_Request_fieldAccessorTable;
436 | }
437 |
438 | // Construct using doozer.DoozerMsg.Request.newBuilder()
439 | private Builder() {
440 | maybeForceBuilderInitialization();
441 | }
442 |
443 | private Builder(BuilderParent parent) {
444 | super(parent);
445 | maybeForceBuilderInitialization();
446 | }
447 | private void maybeForceBuilderInitialization() {
448 | if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
449 | }
450 | }
451 | private static Builder create() {
452 | return new Builder();
453 | }
454 |
455 | public Builder clear() {
456 | super.clear();
457 | tag_ = 0;
458 | bitField0_ = (bitField0_ & ~0x00000001);
459 | verb_ = doozer.DoozerMsg.Request.Verb.GET;
460 | bitField0_ = (bitField0_ & ~0x00000002);
461 | path_ = "";
462 | bitField0_ = (bitField0_ & ~0x00000004);
463 | value_ = com.google.protobuf.ByteString.EMPTY;
464 | bitField0_ = (bitField0_ & ~0x00000008);
465 | otherTag_ = 0;
466 | bitField0_ = (bitField0_ & ~0x00000010);
467 | offset_ = 0;
468 | bitField0_ = (bitField0_ & ~0x00000020);
469 | rev_ = 0L;
470 | bitField0_ = (bitField0_ & ~0x00000040);
471 | return this;
472 | }
473 |
474 | public Builder clone() {
475 | return create().mergeFrom(buildPartial());
476 | }
477 |
478 | public com.google.protobuf.Descriptors.Descriptor
479 | getDescriptorForType() {
480 | return doozer.DoozerMsg.Request.getDescriptor();
481 | }
482 |
483 | public doozer.DoozerMsg.Request getDefaultInstanceForType() {
484 | return doozer.DoozerMsg.Request.getDefaultInstance();
485 | }
486 |
487 | public doozer.DoozerMsg.Request build() {
488 | doozer.DoozerMsg.Request result = buildPartial();
489 | if (!result.isInitialized()) {
490 | throw newUninitializedMessageException(result);
491 | }
492 | return result;
493 | }
494 |
495 | private doozer.DoozerMsg.Request buildParsed()
496 | throws com.google.protobuf.InvalidProtocolBufferException {
497 | doozer.DoozerMsg.Request result = buildPartial();
498 | if (!result.isInitialized()) {
499 | throw newUninitializedMessageException(
500 | result).asInvalidProtocolBufferException();
501 | }
502 | return result;
503 | }
504 |
505 | public doozer.DoozerMsg.Request buildPartial() {
506 | doozer.DoozerMsg.Request result = new doozer.DoozerMsg.Request(this);
507 | int from_bitField0_ = bitField0_;
508 | int to_bitField0_ = 0;
509 | if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
510 | to_bitField0_ |= 0x00000001;
511 | }
512 | result.tag_ = tag_;
513 | if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
514 | to_bitField0_ |= 0x00000002;
515 | }
516 | result.verb_ = verb_;
517 | if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
518 | to_bitField0_ |= 0x00000004;
519 | }
520 | result.path_ = path_;
521 | if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
522 | to_bitField0_ |= 0x00000008;
523 | }
524 | result.value_ = value_;
525 | if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
526 | to_bitField0_ |= 0x00000010;
527 | }
528 | result.otherTag_ = otherTag_;
529 | if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
530 | to_bitField0_ |= 0x00000020;
531 | }
532 | result.offset_ = offset_;
533 | if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
534 | to_bitField0_ |= 0x00000040;
535 | }
536 | result.rev_ = rev_;
537 | result.bitField0_ = to_bitField0_;
538 | onBuilt();
539 | return result;
540 | }
541 |
542 | public Builder mergeFrom(com.google.protobuf.Message other) {
543 | if (other instanceof doozer.DoozerMsg.Request) {
544 | return mergeFrom((doozer.DoozerMsg.Request)other);
545 | } else {
546 | super.mergeFrom(other);
547 | return this;
548 | }
549 | }
550 |
551 | public Builder mergeFrom(doozer.DoozerMsg.Request other) {
552 | if (other == doozer.DoozerMsg.Request.getDefaultInstance()) return this;
553 | if (other.hasTag()) {
554 | setTag(other.getTag());
555 | }
556 | if (other.hasVerb()) {
557 | setVerb(other.getVerb());
558 | }
559 | if (other.hasPath()) {
560 | setPath(other.getPath());
561 | }
562 | if (other.hasValue()) {
563 | setValue(other.getValue());
564 | }
565 | if (other.hasOtherTag()) {
566 | setOtherTag(other.getOtherTag());
567 | }
568 | if (other.hasOffset()) {
569 | setOffset(other.getOffset());
570 | }
571 | if (other.hasRev()) {
572 | setRev(other.getRev());
573 | }
574 | this.mergeUnknownFields(other.getUnknownFields());
575 | return this;
576 | }
577 |
578 | public final boolean isInitialized() {
579 | return true;
580 | }
581 |
582 | public Builder mergeFrom(
583 | com.google.protobuf.CodedInputStream input,
584 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
585 | throws java.io.IOException {
586 | com.google.protobuf.UnknownFieldSet.Builder unknownFields =
587 | com.google.protobuf.UnknownFieldSet.newBuilder(
588 | this.getUnknownFields());
589 | while (true) {
590 | int tag = input.readTag();
591 | switch (tag) {
592 | case 0:
593 | this.setUnknownFields(unknownFields.build());
594 | onChanged();
595 | return this;
596 | default: {
597 | if (!parseUnknownField(input, unknownFields,
598 | extensionRegistry, tag)) {
599 | this.setUnknownFields(unknownFields.build());
600 | onChanged();
601 | return this;
602 | }
603 | break;
604 | }
605 | case 8: {
606 | bitField0_ |= 0x00000001;
607 | tag_ = input.readInt32();
608 | break;
609 | }
610 | case 16: {
611 | int rawValue = input.readEnum();
612 | doozer.DoozerMsg.Request.Verb value = doozer.DoozerMsg.Request.Verb.valueOf(rawValue);
613 | if (value == null) {
614 | unknownFields.mergeVarintField(2, rawValue);
615 | } else {
616 | bitField0_ |= 0x00000002;
617 | verb_ = value;
618 | }
619 | break;
620 | }
621 | case 34: {
622 | bitField0_ |= 0x00000004;
623 | path_ = input.readBytes();
624 | break;
625 | }
626 | case 42: {
627 | bitField0_ |= 0x00000008;
628 | value_ = input.readBytes();
629 | break;
630 | }
631 | case 48: {
632 | bitField0_ |= 0x00000010;
633 | otherTag_ = input.readInt32();
634 | break;
635 | }
636 | case 56: {
637 | bitField0_ |= 0x00000020;
638 | offset_ = input.readInt32();
639 | break;
640 | }
641 | case 72: {
642 | bitField0_ |= 0x00000040;
643 | rev_ = input.readInt64();
644 | break;
645 | }
646 | }
647 | }
648 | }
649 |
650 | private int bitField0_;
651 |
652 | // optional int32 tag = 1;
653 | private int tag_ ;
654 | public boolean hasTag() {
655 | return ((bitField0_ & 0x00000001) == 0x00000001);
656 | }
657 | public int getTag() {
658 | return tag_;
659 | }
660 | public Builder setTag(int value) {
661 | bitField0_ |= 0x00000001;
662 | tag_ = value;
663 | onChanged();
664 | return this;
665 | }
666 | public Builder clearTag() {
667 | bitField0_ = (bitField0_ & ~0x00000001);
668 | tag_ = 0;
669 | onChanged();
670 | return this;
671 | }
672 |
673 | // optional .doozer.Request.Verb verb = 2;
674 | private doozer.DoozerMsg.Request.Verb verb_ = doozer.DoozerMsg.Request.Verb.GET;
675 | public boolean hasVerb() {
676 | return ((bitField0_ & 0x00000002) == 0x00000002);
677 | }
678 | public doozer.DoozerMsg.Request.Verb getVerb() {
679 | return verb_;
680 | }
681 | public Builder setVerb(doozer.DoozerMsg.Request.Verb value) {
682 | if (value == null) {
683 | throw new NullPointerException();
684 | }
685 | bitField0_ |= 0x00000002;
686 | verb_ = value;
687 | onChanged();
688 | return this;
689 | }
690 | public Builder clearVerb() {
691 | bitField0_ = (bitField0_ & ~0x00000002);
692 | verb_ = doozer.DoozerMsg.Request.Verb.GET;
693 | onChanged();
694 | return this;
695 | }
696 |
697 | // optional string path = 4;
698 | private Object path_ = "";
699 | public boolean hasPath() {
700 | return ((bitField0_ & 0x00000004) == 0x00000004);
701 | }
702 | public String getPath() {
703 | Object ref = path_;
704 | if (!(ref instanceof String)) {
705 | String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
706 | path_ = s;
707 | return s;
708 | } else {
709 | return (String) ref;
710 | }
711 | }
712 | public Builder setPath(String value) {
713 | if (value == null) {
714 | throw new NullPointerException();
715 | }
716 | bitField0_ |= 0x00000004;
717 | path_ = value;
718 | onChanged();
719 | return this;
720 | }
721 | public Builder clearPath() {
722 | bitField0_ = (bitField0_ & ~0x00000004);
723 | path_ = getDefaultInstance().getPath();
724 | onChanged();
725 | return this;
726 | }
727 | void setPath(com.google.protobuf.ByteString value) {
728 | bitField0_ |= 0x00000004;
729 | path_ = value;
730 | onChanged();
731 | }
732 |
733 | // optional bytes value = 5;
734 | private com.google.protobuf.ByteString value_ = com.google.protobuf.ByteString.EMPTY;
735 | public boolean hasValue() {
736 | return ((bitField0_ & 0x00000008) == 0x00000008);
737 | }
738 | public com.google.protobuf.ByteString getValue() {
739 | return value_;
740 | }
741 | public Builder setValue(com.google.protobuf.ByteString value) {
742 | if (value == null) {
743 | throw new NullPointerException();
744 | }
745 | bitField0_ |= 0x00000008;
746 | value_ = value;
747 | onChanged();
748 | return this;
749 | }
750 | public Builder clearValue() {
751 | bitField0_ = (bitField0_ & ~0x00000008);
752 | value_ = getDefaultInstance().getValue();
753 | onChanged();
754 | return this;
755 | }
756 |
757 | // optional int32 other_tag = 6;
758 | private int otherTag_ ;
759 | public boolean hasOtherTag() {
760 | return ((bitField0_ & 0x00000010) == 0x00000010);
761 | }
762 | public int getOtherTag() {
763 | return otherTag_;
764 | }
765 | public Builder setOtherTag(int value) {
766 | bitField0_ |= 0x00000010;
767 | otherTag_ = value;
768 | onChanged();
769 | return this;
770 | }
771 | public Builder clearOtherTag() {
772 | bitField0_ = (bitField0_ & ~0x00000010);
773 | otherTag_ = 0;
774 | onChanged();
775 | return this;
776 | }
777 |
778 | // optional int32 offset = 7;
779 | private int offset_ ;
780 | public boolean hasOffset() {
781 | return ((bitField0_ & 0x00000020) == 0x00000020);
782 | }
783 | public int getOffset() {
784 | return offset_;
785 | }
786 | public Builder setOffset(int value) {
787 | bitField0_ |= 0x00000020;
788 | offset_ = value;
789 | onChanged();
790 | return this;
791 | }
792 | public Builder clearOffset() {
793 | bitField0_ = (bitField0_ & ~0x00000020);
794 | offset_ = 0;
795 | onChanged();
796 | return this;
797 | }
798 |
799 | // optional int64 rev = 9;
800 | private long rev_ ;
801 | public boolean hasRev() {
802 | return ((bitField0_ & 0x00000040) == 0x00000040);
803 | }
804 | public long getRev() {
805 | return rev_;
806 | }
807 | public Builder setRev(long value) {
808 | bitField0_ |= 0x00000040;
809 | rev_ = value;
810 | onChanged();
811 | return this;
812 | }
813 | public Builder clearRev() {
814 | bitField0_ = (bitField0_ & ~0x00000040);
815 | rev_ = 0L;
816 | onChanged();
817 | return this;
818 | }
819 |
820 | // @@protoc_insertion_point(builder_scope:doozer.Request)
821 | }
822 |
823 | static {
824 | defaultInstance = new Request(true);
825 | defaultInstance.initFields();
826 | }
827 |
828 | // @@protoc_insertion_point(class_scope:doozer.Request)
829 | }
830 |
831 | public interface ResponseOrBuilder
832 | extends com.google.protobuf.MessageOrBuilder {
833 |
834 | // optional int32 tag = 1;
835 | boolean hasTag();
836 | int getTag();
837 |
838 | // optional int32 flags = 2;
839 | boolean hasFlags();
840 | int getFlags();
841 |
842 | // optional int64 rev = 3;
843 | boolean hasRev();
844 | long getRev();
845 |
846 | // optional string path = 5;
847 | boolean hasPath();
848 | String getPath();
849 |
850 | // optional bytes value = 6;
851 | boolean hasValue();
852 | com.google.protobuf.ByteString getValue();
853 |
854 | // optional int32 len = 8;
855 | boolean hasLen();
856 | int getLen();
857 |
858 | // optional .doozer.Response.Err err_code = 100;
859 | boolean hasErrCode();
860 | doozer.DoozerMsg.Response.Err getErrCode();
861 |
862 | // optional string err_detail = 101;
863 | boolean hasErrDetail();
864 | String getErrDetail();
865 | }
866 | public static final class Response extends
867 | com.google.protobuf.GeneratedMessage
868 | implements ResponseOrBuilder {
869 | // Use Response.newBuilder() to construct.
870 | private Response(Builder builder) {
871 | super(builder);
872 | }
873 | private Response(boolean noInit) {}
874 |
875 | private static final Response defaultInstance;
876 | public static Response getDefaultInstance() {
877 | return defaultInstance;
878 | }
879 |
880 | public Response getDefaultInstanceForType() {
881 | return defaultInstance;
882 | }
883 |
884 | public static final com.google.protobuf.Descriptors.Descriptor
885 | getDescriptor() {
886 | return doozer.DoozerMsg.internal_static_doozer_Response_descriptor;
887 | }
888 |
889 | protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
890 | internalGetFieldAccessorTable() {
891 | return doozer.DoozerMsg.internal_static_doozer_Response_fieldAccessorTable;
892 | }
893 |
894 | public enum Err
895 | implements com.google.protobuf.ProtocolMessageEnum {
896 | OTHER(0, 127),
897 | TAG_IN_USE(1, 1),
898 | UNKNOWN_VERB(2, 2),
899 | READONLY(3, 3),
900 | TOO_LATE(4, 4),
901 | REV_MISMATCH(5, 5),
902 | BAD_PATH(6, 6),
903 | MISSING_ARG(7, 7),
904 | RANGE(8, 8),
905 | NOTDIR(9, 20),
906 | ISDIR(10, 21),
907 | NOENT(11, 22),
908 | ;
909 |
910 | public static final int OTHER_VALUE = 127;
911 | public static final int TAG_IN_USE_VALUE = 1;
912 | public static final int UNKNOWN_VERB_VALUE = 2;
913 | public static final int READONLY_VALUE = 3;
914 | public static final int TOO_LATE_VALUE = 4;
915 | public static final int REV_MISMATCH_VALUE = 5;
916 | public static final int BAD_PATH_VALUE = 6;
917 | public static final int MISSING_ARG_VALUE = 7;
918 | public static final int RANGE_VALUE = 8;
919 | public static final int NOTDIR_VALUE = 20;
920 | public static final int ISDIR_VALUE = 21;
921 | public static final int NOENT_VALUE = 22;
922 |
923 |
924 | public final int getNumber() { return value; }
925 |
926 | public static Err valueOf(int value) {
927 | switch (value) {
928 | case 127: return OTHER;
929 | case 1: return TAG_IN_USE;
930 | case 2: return UNKNOWN_VERB;
931 | case 3: return READONLY;
932 | case 4: return TOO_LATE;
933 | case 5: return REV_MISMATCH;
934 | case 6: return BAD_PATH;
935 | case 7: return MISSING_ARG;
936 | case 8: return RANGE;
937 | case 20: return NOTDIR;
938 | case 21: return ISDIR;
939 | case 22: return NOENT;
940 | default: return null;
941 | }
942 | }
943 |
944 | public static com.google.protobuf.Internal.EnumLiteMap
945 | internalGetValueMap() {
946 | return internalValueMap;
947 | }
948 | private static com.google.protobuf.Internal.EnumLiteMap
949 | internalValueMap =
950 | new com.google.protobuf.Internal.EnumLiteMap() {
951 | public Err findValueByNumber(int number) {
952 | return Err.valueOf(number);
953 | }
954 | };
955 |
956 | public final com.google.protobuf.Descriptors.EnumValueDescriptor
957 | getValueDescriptor() {
958 | return getDescriptor().getValues().get(index);
959 | }
960 | public final com.google.protobuf.Descriptors.EnumDescriptor
961 | getDescriptorForType() {
962 | return getDescriptor();
963 | }
964 | public static final com.google.protobuf.Descriptors.EnumDescriptor
965 | getDescriptor() {
966 | return doozer.DoozerMsg.Response.getDescriptor().getEnumTypes().get(0);
967 | }
968 |
969 | private static final Err[] VALUES = {
970 | OTHER, TAG_IN_USE, UNKNOWN_VERB, READONLY, TOO_LATE, REV_MISMATCH, BAD_PATH, MISSING_ARG, RANGE, NOTDIR, ISDIR, NOENT,
971 | };
972 |
973 | public static Err valueOf(
974 | com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
975 | if (desc.getType() != getDescriptor()) {
976 | throw new java.lang.IllegalArgumentException(
977 | "EnumValueDescriptor is not for this type.");
978 | }
979 | return VALUES[desc.getIndex()];
980 | }
981 |
982 | private final int index;
983 | private final int value;
984 |
985 | private Err(int index, int value) {
986 | this.index = index;
987 | this.value = value;
988 | }
989 |
990 | // @@protoc_insertion_point(enum_scope:doozer.Response.Err)
991 | }
992 |
993 | private int bitField0_;
994 | // optional int32 tag = 1;
995 | public static final int TAG_FIELD_NUMBER = 1;
996 | private int tag_;
997 | public boolean hasTag() {
998 | return ((bitField0_ & 0x00000001) == 0x00000001);
999 | }
1000 | public int getTag() {
1001 | return tag_;
1002 | }
1003 |
1004 | // optional int32 flags = 2;
1005 | public static final int FLAGS_FIELD_NUMBER = 2;
1006 | private int flags_;
1007 | public boolean hasFlags() {
1008 | return ((bitField0_ & 0x00000002) == 0x00000002);
1009 | }
1010 | public int getFlags() {
1011 | return flags_;
1012 | }
1013 |
1014 | // optional int64 rev = 3;
1015 | public static final int REV_FIELD_NUMBER = 3;
1016 | private long rev_;
1017 | public boolean hasRev() {
1018 | return ((bitField0_ & 0x00000004) == 0x00000004);
1019 | }
1020 | public long getRev() {
1021 | return rev_;
1022 | }
1023 |
1024 | // optional string path = 5;
1025 | public static final int PATH_FIELD_NUMBER = 5;
1026 | private Object path_;
1027 | public boolean hasPath() {
1028 | return ((bitField0_ & 0x00000008) == 0x00000008);
1029 | }
1030 | public String getPath() {
1031 | Object ref = path_;
1032 | if (ref instanceof String) {
1033 | return (String) ref;
1034 | } else {
1035 | com.google.protobuf.ByteString bs =
1036 | (com.google.protobuf.ByteString) ref;
1037 | String s = bs.toStringUtf8();
1038 | if (com.google.protobuf.Internal.isValidUtf8(bs)) {
1039 | path_ = s;
1040 | }
1041 | return s;
1042 | }
1043 | }
1044 | private com.google.protobuf.ByteString getPathBytes() {
1045 | Object ref = path_;
1046 | if (ref instanceof String) {
1047 | com.google.protobuf.ByteString b =
1048 | com.google.protobuf.ByteString.copyFromUtf8((String) ref);
1049 | path_ = b;
1050 | return b;
1051 | } else {
1052 | return (com.google.protobuf.ByteString) ref;
1053 | }
1054 | }
1055 |
1056 | // optional bytes value = 6;
1057 | public static final int VALUE_FIELD_NUMBER = 6;
1058 | private com.google.protobuf.ByteString value_;
1059 | public boolean hasValue() {
1060 | return ((bitField0_ & 0x00000010) == 0x00000010);
1061 | }
1062 | public com.google.protobuf.ByteString getValue() {
1063 | return value_;
1064 | }
1065 |
1066 | // optional int32 len = 8;
1067 | public static final int LEN_FIELD_NUMBER = 8;
1068 | private int len_;
1069 | public boolean hasLen() {
1070 | return ((bitField0_ & 0x00000020) == 0x00000020);
1071 | }
1072 | public int getLen() {
1073 | return len_;
1074 | }
1075 |
1076 | // optional .doozer.Response.Err err_code = 100;
1077 | public static final int ERR_CODE_FIELD_NUMBER = 100;
1078 | private doozer.DoozerMsg.Response.Err errCode_;
1079 | public boolean hasErrCode() {
1080 | return ((bitField0_ & 0x00000040) == 0x00000040);
1081 | }
1082 | public doozer.DoozerMsg.Response.Err getErrCode() {
1083 | return errCode_;
1084 | }
1085 |
1086 | // optional string err_detail = 101;
1087 | public static final int ERR_DETAIL_FIELD_NUMBER = 101;
1088 | private Object errDetail_;
1089 | public boolean hasErrDetail() {
1090 | return ((bitField0_ & 0x00000080) == 0x00000080);
1091 | }
1092 | public String getErrDetail() {
1093 | Object ref = errDetail_;
1094 | if (ref instanceof String) {
1095 | return (String) ref;
1096 | } else {
1097 | com.google.protobuf.ByteString bs =
1098 | (com.google.protobuf.ByteString) ref;
1099 | String s = bs.toStringUtf8();
1100 | if (com.google.protobuf.Internal.isValidUtf8(bs)) {
1101 | errDetail_ = s;
1102 | }
1103 | return s;
1104 | }
1105 | }
1106 | private com.google.protobuf.ByteString getErrDetailBytes() {
1107 | Object ref = errDetail_;
1108 | if (ref instanceof String) {
1109 | com.google.protobuf.ByteString b =
1110 | com.google.protobuf.ByteString.copyFromUtf8((String) ref);
1111 | errDetail_ = b;
1112 | return b;
1113 | } else {
1114 | return (com.google.protobuf.ByteString) ref;
1115 | }
1116 | }
1117 |
1118 | private void initFields() {
1119 | tag_ = 0;
1120 | flags_ = 0;
1121 | rev_ = 0L;
1122 | path_ = "";
1123 | value_ = com.google.protobuf.ByteString.EMPTY;
1124 | len_ = 0;
1125 | errCode_ = doozer.DoozerMsg.Response.Err.OTHER;
1126 | errDetail_ = "";
1127 | }
1128 | private byte memoizedIsInitialized = -1;
1129 | public final boolean isInitialized() {
1130 | byte isInitialized = memoizedIsInitialized;
1131 | if (isInitialized != -1) return isInitialized == 1;
1132 |
1133 | memoizedIsInitialized = 1;
1134 | return true;
1135 | }
1136 |
1137 | public void writeTo(com.google.protobuf.CodedOutputStream output)
1138 | throws java.io.IOException {
1139 | getSerializedSize();
1140 | if (((bitField0_ & 0x00000001) == 0x00000001)) {
1141 | output.writeInt32(1, tag_);
1142 | }
1143 | if (((bitField0_ & 0x00000002) == 0x00000002)) {
1144 | output.writeInt32(2, flags_);
1145 | }
1146 | if (((bitField0_ & 0x00000004) == 0x00000004)) {
1147 | output.writeInt64(3, rev_);
1148 | }
1149 | if (((bitField0_ & 0x00000008) == 0x00000008)) {
1150 | output.writeBytes(5, getPathBytes());
1151 | }
1152 | if (((bitField0_ & 0x00000010) == 0x00000010)) {
1153 | output.writeBytes(6, value_);
1154 | }
1155 | if (((bitField0_ & 0x00000020) == 0x00000020)) {
1156 | output.writeInt32(8, len_);
1157 | }
1158 | if (((bitField0_ & 0x00000040) == 0x00000040)) {
1159 | output.writeEnum(100, errCode_.getNumber());
1160 | }
1161 | if (((bitField0_ & 0x00000080) == 0x00000080)) {
1162 | output.writeBytes(101, getErrDetailBytes());
1163 | }
1164 | getUnknownFields().writeTo(output);
1165 | }
1166 |
1167 | private int memoizedSerializedSize = -1;
1168 | public int getSerializedSize() {
1169 | int size = memoizedSerializedSize;
1170 | if (size != -1) return size;
1171 |
1172 | size = 0;
1173 | if (((bitField0_ & 0x00000001) == 0x00000001)) {
1174 | size += com.google.protobuf.CodedOutputStream
1175 | .computeInt32Size(1, tag_);
1176 | }
1177 | if (((bitField0_ & 0x00000002) == 0x00000002)) {
1178 | size += com.google.protobuf.CodedOutputStream
1179 | .computeInt32Size(2, flags_);
1180 | }
1181 | if (((bitField0_ & 0x00000004) == 0x00000004)) {
1182 | size += com.google.protobuf.CodedOutputStream
1183 | .computeInt64Size(3, rev_);
1184 | }
1185 | if (((bitField0_ & 0x00000008) == 0x00000008)) {
1186 | size += com.google.protobuf.CodedOutputStream
1187 | .computeBytesSize(5, getPathBytes());
1188 | }
1189 | if (((bitField0_ & 0x00000010) == 0x00000010)) {
1190 | size += com.google.protobuf.CodedOutputStream
1191 | .computeBytesSize(6, value_);
1192 | }
1193 | if (((bitField0_ & 0x00000020) == 0x00000020)) {
1194 | size += com.google.protobuf.CodedOutputStream
1195 | .computeInt32Size(8, len_);
1196 | }
1197 | if (((bitField0_ & 0x00000040) == 0x00000040)) {
1198 | size += com.google.protobuf.CodedOutputStream
1199 | .computeEnumSize(100, errCode_.getNumber());
1200 | }
1201 | if (((bitField0_ & 0x00000080) == 0x00000080)) {
1202 | size += com.google.protobuf.CodedOutputStream
1203 | .computeBytesSize(101, getErrDetailBytes());
1204 | }
1205 | size += getUnknownFields().getSerializedSize();
1206 | memoizedSerializedSize = size;
1207 | return size;
1208 | }
1209 |
1210 | @java.lang.Override
1211 | protected Object writeReplace() throws java.io.ObjectStreamException {
1212 | return super.writeReplace();
1213 | }
1214 |
1215 | public static doozer.DoozerMsg.Response parseFrom(
1216 | com.google.protobuf.ByteString data)
1217 | throws com.google.protobuf.InvalidProtocolBufferException {
1218 | return newBuilder().mergeFrom(data).buildParsed();
1219 | }
1220 | public static doozer.DoozerMsg.Response parseFrom(
1221 | com.google.protobuf.ByteString data,
1222 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
1223 | throws com.google.protobuf.InvalidProtocolBufferException {
1224 | return newBuilder().mergeFrom(data, extensionRegistry)
1225 | .buildParsed();
1226 | }
1227 | public static doozer.DoozerMsg.Response parseFrom(byte[] data)
1228 | throws com.google.protobuf.InvalidProtocolBufferException {
1229 | return newBuilder().mergeFrom(data).buildParsed();
1230 | }
1231 | public static doozer.DoozerMsg.Response parseFrom(
1232 | byte[] data,
1233 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
1234 | throws com.google.protobuf.InvalidProtocolBufferException {
1235 | return newBuilder().mergeFrom(data, extensionRegistry)
1236 | .buildParsed();
1237 | }
1238 | public static doozer.DoozerMsg.Response parseFrom(java.io.InputStream input)
1239 | throws java.io.IOException {
1240 | return newBuilder().mergeFrom(input).buildParsed();
1241 | }
1242 | public static doozer.DoozerMsg.Response parseFrom(
1243 | java.io.InputStream input,
1244 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
1245 | throws java.io.IOException {
1246 | return newBuilder().mergeFrom(input, extensionRegistry)
1247 | .buildParsed();
1248 | }
1249 | public static doozer.DoozerMsg.Response parseDelimitedFrom(java.io.InputStream input)
1250 | throws java.io.IOException {
1251 | Builder builder = newBuilder();
1252 | if (builder.mergeDelimitedFrom(input)) {
1253 | return builder.buildParsed();
1254 | } else {
1255 | return null;
1256 | }
1257 | }
1258 | public static doozer.DoozerMsg.Response parseDelimitedFrom(
1259 | java.io.InputStream input,
1260 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
1261 | throws java.io.IOException {
1262 | Builder builder = newBuilder();
1263 | if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
1264 | return builder.buildParsed();
1265 | } else {
1266 | return null;
1267 | }
1268 | }
1269 | public static doozer.DoozerMsg.Response parseFrom(
1270 | com.google.protobuf.CodedInputStream input)
1271 | throws java.io.IOException {
1272 | return newBuilder().mergeFrom(input).buildParsed();
1273 | }
1274 | public static doozer.DoozerMsg.Response parseFrom(
1275 | com.google.protobuf.CodedInputStream input,
1276 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
1277 | throws java.io.IOException {
1278 | return newBuilder().mergeFrom(input, extensionRegistry)
1279 | .buildParsed();
1280 | }
1281 |
1282 | public static Builder newBuilder() { return Builder.create(); }
1283 | public Builder newBuilderForType() { return newBuilder(); }
1284 | public static Builder newBuilder(doozer.DoozerMsg.Response prototype) {
1285 | return newBuilder().mergeFrom(prototype);
1286 | }
1287 | public Builder toBuilder() { return newBuilder(this); }
1288 |
1289 | @java.lang.Override
1290 | protected Builder newBuilderForType(
1291 | com.google.protobuf.GeneratedMessage.BuilderParent parent) {
1292 | Builder builder = new Builder(parent);
1293 | return builder;
1294 | }
1295 | public static final class Builder extends
1296 | com.google.protobuf.GeneratedMessage.Builder
1297 | implements doozer.DoozerMsg.ResponseOrBuilder {
1298 | public static final com.google.protobuf.Descriptors.Descriptor
1299 | getDescriptor() {
1300 | return doozer.DoozerMsg.internal_static_doozer_Response_descriptor;
1301 | }
1302 |
1303 | protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
1304 | internalGetFieldAccessorTable() {
1305 | return doozer.DoozerMsg.internal_static_doozer_Response_fieldAccessorTable;
1306 | }
1307 |
1308 | // Construct using doozer.DoozerMsg.Response.newBuilder()
1309 | private Builder() {
1310 | maybeForceBuilderInitialization();
1311 | }
1312 |
1313 | private Builder(BuilderParent parent) {
1314 | super(parent);
1315 | maybeForceBuilderInitialization();
1316 | }
1317 | private void maybeForceBuilderInitialization() {
1318 | if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
1319 | }
1320 | }
1321 | private static Builder create() {
1322 | return new Builder();
1323 | }
1324 |
1325 | public Builder clear() {
1326 | super.clear();
1327 | tag_ = 0;
1328 | bitField0_ = (bitField0_ & ~0x00000001);
1329 | flags_ = 0;
1330 | bitField0_ = (bitField0_ & ~0x00000002);
1331 | rev_ = 0L;
1332 | bitField0_ = (bitField0_ & ~0x00000004);
1333 | path_ = "";
1334 | bitField0_ = (bitField0_ & ~0x00000008);
1335 | value_ = com.google.protobuf.ByteString.EMPTY;
1336 | bitField0_ = (bitField0_ & ~0x00000010);
1337 | len_ = 0;
1338 | bitField0_ = (bitField0_ & ~0x00000020);
1339 | errCode_ = doozer.DoozerMsg.Response.Err.OTHER;
1340 | bitField0_ = (bitField0_ & ~0x00000040);
1341 | errDetail_ = "";
1342 | bitField0_ = (bitField0_ & ~0x00000080);
1343 | return this;
1344 | }
1345 |
1346 | public Builder clone() {
1347 | return create().mergeFrom(buildPartial());
1348 | }
1349 |
1350 | public com.google.protobuf.Descriptors.Descriptor
1351 | getDescriptorForType() {
1352 | return doozer.DoozerMsg.Response.getDescriptor();
1353 | }
1354 |
1355 | public doozer.DoozerMsg.Response getDefaultInstanceForType() {
1356 | return doozer.DoozerMsg.Response.getDefaultInstance();
1357 | }
1358 |
1359 | public doozer.DoozerMsg.Response build() {
1360 | doozer.DoozerMsg.Response result = buildPartial();
1361 | if (!result.isInitialized()) {
1362 | throw newUninitializedMessageException(result);
1363 | }
1364 | return result;
1365 | }
1366 |
1367 | private doozer.DoozerMsg.Response buildParsed()
1368 | throws com.google.protobuf.InvalidProtocolBufferException {
1369 | doozer.DoozerMsg.Response result = buildPartial();
1370 | if (!result.isInitialized()) {
1371 | throw newUninitializedMessageException(
1372 | result).asInvalidProtocolBufferException();
1373 | }
1374 | return result;
1375 | }
1376 |
1377 | public doozer.DoozerMsg.Response buildPartial() {
1378 | doozer.DoozerMsg.Response result = new doozer.DoozerMsg.Response(this);
1379 | int from_bitField0_ = bitField0_;
1380 | int to_bitField0_ = 0;
1381 | if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
1382 | to_bitField0_ |= 0x00000001;
1383 | }
1384 | result.tag_ = tag_;
1385 | if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
1386 | to_bitField0_ |= 0x00000002;
1387 | }
1388 | result.flags_ = flags_;
1389 | if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
1390 | to_bitField0_ |= 0x00000004;
1391 | }
1392 | result.rev_ = rev_;
1393 | if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
1394 | to_bitField0_ |= 0x00000008;
1395 | }
1396 | result.path_ = path_;
1397 | if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
1398 | to_bitField0_ |= 0x00000010;
1399 | }
1400 | result.value_ = value_;
1401 | if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
1402 | to_bitField0_ |= 0x00000020;
1403 | }
1404 | result.len_ = len_;
1405 | if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
1406 | to_bitField0_ |= 0x00000040;
1407 | }
1408 | result.errCode_ = errCode_;
1409 | if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
1410 | to_bitField0_ |= 0x00000080;
1411 | }
1412 | result.errDetail_ = errDetail_;
1413 | result.bitField0_ = to_bitField0_;
1414 | onBuilt();
1415 | return result;
1416 | }
1417 |
1418 | public Builder mergeFrom(com.google.protobuf.Message other) {
1419 | if (other instanceof doozer.DoozerMsg.Response) {
1420 | return mergeFrom((doozer.DoozerMsg.Response)other);
1421 | } else {
1422 | super.mergeFrom(other);
1423 | return this;
1424 | }
1425 | }
1426 |
1427 | public Builder mergeFrom(doozer.DoozerMsg.Response other) {
1428 | if (other == doozer.DoozerMsg.Response.getDefaultInstance()) return this;
1429 | if (other.hasTag()) {
1430 | setTag(other.getTag());
1431 | }
1432 | if (other.hasFlags()) {
1433 | setFlags(other.getFlags());
1434 | }
1435 | if (other.hasRev()) {
1436 | setRev(other.getRev());
1437 | }
1438 | if (other.hasPath()) {
1439 | setPath(other.getPath());
1440 | }
1441 | if (other.hasValue()) {
1442 | setValue(other.getValue());
1443 | }
1444 | if (other.hasLen()) {
1445 | setLen(other.getLen());
1446 | }
1447 | if (other.hasErrCode()) {
1448 | setErrCode(other.getErrCode());
1449 | }
1450 | if (other.hasErrDetail()) {
1451 | setErrDetail(other.getErrDetail());
1452 | }
1453 | this.mergeUnknownFields(other.getUnknownFields());
1454 | return this;
1455 | }
1456 |
1457 | public final boolean isInitialized() {
1458 | return true;
1459 | }
1460 |
1461 | public Builder mergeFrom(
1462 | com.google.protobuf.CodedInputStream input,
1463 | com.google.protobuf.ExtensionRegistryLite extensionRegistry)
1464 | throws java.io.IOException {
1465 | com.google.protobuf.UnknownFieldSet.Builder unknownFields =
1466 | com.google.protobuf.UnknownFieldSet.newBuilder(
1467 | this.getUnknownFields());
1468 | while (true) {
1469 | int tag = input.readTag();
1470 | switch (tag) {
1471 | case 0:
1472 | this.setUnknownFields(unknownFields.build());
1473 | onChanged();
1474 | return this;
1475 | default: {
1476 | if (!parseUnknownField(input, unknownFields,
1477 | extensionRegistry, tag)) {
1478 | this.setUnknownFields(unknownFields.build());
1479 | onChanged();
1480 | return this;
1481 | }
1482 | break;
1483 | }
1484 | case 8: {
1485 | bitField0_ |= 0x00000001;
1486 | tag_ = input.readInt32();
1487 | break;
1488 | }
1489 | case 16: {
1490 | bitField0_ |= 0x00000002;
1491 | flags_ = input.readInt32();
1492 | break;
1493 | }
1494 | case 24: {
1495 | bitField0_ |= 0x00000004;
1496 | rev_ = input.readInt64();
1497 | break;
1498 | }
1499 | case 42: {
1500 | bitField0_ |= 0x00000008;
1501 | path_ = input.readBytes();
1502 | break;
1503 | }
1504 | case 50: {
1505 | bitField0_ |= 0x00000010;
1506 | value_ = input.readBytes();
1507 | break;
1508 | }
1509 | case 64: {
1510 | bitField0_ |= 0x00000020;
1511 | len_ = input.readInt32();
1512 | break;
1513 | }
1514 | case 800: {
1515 | int rawValue = input.readEnum();
1516 | doozer.DoozerMsg.Response.Err value = doozer.DoozerMsg.Response.Err.valueOf(rawValue);
1517 | if (value == null) {
1518 | unknownFields.mergeVarintField(100, rawValue);
1519 | } else {
1520 | bitField0_ |= 0x00000040;
1521 | errCode_ = value;
1522 | }
1523 | break;
1524 | }
1525 | case 810: {
1526 | bitField0_ |= 0x00000080;
1527 | errDetail_ = input.readBytes();
1528 | break;
1529 | }
1530 | }
1531 | }
1532 | }
1533 |
1534 | private int bitField0_;
1535 |
1536 | // optional int32 tag = 1;
1537 | private int tag_ ;
1538 | public boolean hasTag() {
1539 | return ((bitField0_ & 0x00000001) == 0x00000001);
1540 | }
1541 | public int getTag() {
1542 | return tag_;
1543 | }
1544 | public Builder setTag(int value) {
1545 | bitField0_ |= 0x00000001;
1546 | tag_ = value;
1547 | onChanged();
1548 | return this;
1549 | }
1550 | public Builder clearTag() {
1551 | bitField0_ = (bitField0_ & ~0x00000001);
1552 | tag_ = 0;
1553 | onChanged();
1554 | return this;
1555 | }
1556 |
1557 | // optional int32 flags = 2;
1558 | private int flags_ ;
1559 | public boolean hasFlags() {
1560 | return ((bitField0_ & 0x00000002) == 0x00000002);
1561 | }
1562 | public int getFlags() {
1563 | return flags_;
1564 | }
1565 | public Builder setFlags(int value) {
1566 | bitField0_ |= 0x00000002;
1567 | flags_ = value;
1568 | onChanged();
1569 | return this;
1570 | }
1571 | public Builder clearFlags() {
1572 | bitField0_ = (bitField0_ & ~0x00000002);
1573 | flags_ = 0;
1574 | onChanged();
1575 | return this;
1576 | }
1577 |
1578 | // optional int64 rev = 3;
1579 | private long rev_ ;
1580 | public boolean hasRev() {
1581 | return ((bitField0_ & 0x00000004) == 0x00000004);
1582 | }
1583 | public long getRev() {
1584 | return rev_;
1585 | }
1586 | public Builder setRev(long value) {
1587 | bitField0_ |= 0x00000004;
1588 | rev_ = value;
1589 | onChanged();
1590 | return this;
1591 | }
1592 | public Builder clearRev() {
1593 | bitField0_ = (bitField0_ & ~0x00000004);
1594 | rev_ = 0L;
1595 | onChanged();
1596 | return this;
1597 | }
1598 |
1599 | // optional string path = 5;
1600 | private Object path_ = "";
1601 | public boolean hasPath() {
1602 | return ((bitField0_ & 0x00000008) == 0x00000008);
1603 | }
1604 | public String getPath() {
1605 | Object ref = path_;
1606 | if (!(ref instanceof String)) {
1607 | String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
1608 | path_ = s;
1609 | return s;
1610 | } else {
1611 | return (String) ref;
1612 | }
1613 | }
1614 | public Builder setPath(String value) {
1615 | if (value == null) {
1616 | throw new NullPointerException();
1617 | }
1618 | bitField0_ |= 0x00000008;
1619 | path_ = value;
1620 | onChanged();
1621 | return this;
1622 | }
1623 | public Builder clearPath() {
1624 | bitField0_ = (bitField0_ & ~0x00000008);
1625 | path_ = getDefaultInstance().getPath();
1626 | onChanged();
1627 | return this;
1628 | }
1629 | void setPath(com.google.protobuf.ByteString value) {
1630 | bitField0_ |= 0x00000008;
1631 | path_ = value;
1632 | onChanged();
1633 | }
1634 |
1635 | // optional bytes value = 6;
1636 | private com.google.protobuf.ByteString value_ = com.google.protobuf.ByteString.EMPTY;
1637 | public boolean hasValue() {
1638 | return ((bitField0_ & 0x00000010) == 0x00000010);
1639 | }
1640 | public com.google.protobuf.ByteString getValue() {
1641 | return value_;
1642 | }
1643 | public Builder setValue(com.google.protobuf.ByteString value) {
1644 | if (value == null) {
1645 | throw new NullPointerException();
1646 | }
1647 | bitField0_ |= 0x00000010;
1648 | value_ = value;
1649 | onChanged();
1650 | return this;
1651 | }
1652 | public Builder clearValue() {
1653 | bitField0_ = (bitField0_ & ~0x00000010);
1654 | value_ = getDefaultInstance().getValue();
1655 | onChanged();
1656 | return this;
1657 | }
1658 |
1659 | // optional int32 len = 8;
1660 | private int len_ ;
1661 | public boolean hasLen() {
1662 | return ((bitField0_ & 0x00000020) == 0x00000020);
1663 | }
1664 | public int getLen() {
1665 | return len_;
1666 | }
1667 | public Builder setLen(int value) {
1668 | bitField0_ |= 0x00000020;
1669 | len_ = value;
1670 | onChanged();
1671 | return this;
1672 | }
1673 | public Builder clearLen() {
1674 | bitField0_ = (bitField0_ & ~0x00000020);
1675 | len_ = 0;
1676 | onChanged();
1677 | return this;
1678 | }
1679 |
1680 | // optional .doozer.Response.Err err_code = 100;
1681 | private doozer.DoozerMsg.Response.Err errCode_ = doozer.DoozerMsg.Response.Err.OTHER;
1682 | public boolean hasErrCode() {
1683 | return ((bitField0_ & 0x00000040) == 0x00000040);
1684 | }
1685 | public doozer.DoozerMsg.Response.Err getErrCode() {
1686 | return errCode_;
1687 | }
1688 | public Builder setErrCode(doozer.DoozerMsg.Response.Err value) {
1689 | if (value == null) {
1690 | throw new NullPointerException();
1691 | }
1692 | bitField0_ |= 0x00000040;
1693 | errCode_ = value;
1694 | onChanged();
1695 | return this;
1696 | }
1697 | public Builder clearErrCode() {
1698 | bitField0_ = (bitField0_ & ~0x00000040);
1699 | errCode_ = doozer.DoozerMsg.Response.Err.OTHER;
1700 | onChanged();
1701 | return this;
1702 | }
1703 |
1704 | // optional string err_detail = 101;
1705 | private Object errDetail_ = "";
1706 | public boolean hasErrDetail() {
1707 | return ((bitField0_ & 0x00000080) == 0x00000080);
1708 | }
1709 | public String getErrDetail() {
1710 | Object ref = errDetail_;
1711 | if (!(ref instanceof String)) {
1712 | String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
1713 | errDetail_ = s;
1714 | return s;
1715 | } else {
1716 | return (String) ref;
1717 | }
1718 | }
1719 | public Builder setErrDetail(String value) {
1720 | if (value == null) {
1721 | throw new NullPointerException();
1722 | }
1723 | bitField0_ |= 0x00000080;
1724 | errDetail_ = value;
1725 | onChanged();
1726 | return this;
1727 | }
1728 | public Builder clearErrDetail() {
1729 | bitField0_ = (bitField0_ & ~0x00000080);
1730 | errDetail_ = getDefaultInstance().getErrDetail();
1731 | onChanged();
1732 | return this;
1733 | }
1734 | void setErrDetail(com.google.protobuf.ByteString value) {
1735 | bitField0_ |= 0x00000080;
1736 | errDetail_ = value;
1737 | onChanged();
1738 | }
1739 |
1740 | // @@protoc_insertion_point(builder_scope:doozer.Response)
1741 | }
1742 |
1743 | static {
1744 | defaultInstance = new Response(true);
1745 | defaultInstance.initFields();
1746 | }
1747 |
1748 | // @@protoc_insertion_point(class_scope:doozer.Response)
1749 | }
1750 |
1751 | private static com.google.protobuf.Descriptors.Descriptor
1752 | internal_static_doozer_Request_descriptor;
1753 | private static
1754 | com.google.protobuf.GeneratedMessage.FieldAccessorTable
1755 | internal_static_doozer_Request_fieldAccessorTable;
1756 | private static com.google.protobuf.Descriptors.Descriptor
1757 | internal_static_doozer_Response_descriptor;
1758 | private static
1759 | com.google.protobuf.GeneratedMessage.FieldAccessorTable
1760 | internal_static_doozer_Response_fieldAccessorTable;
1761 |
1762 | public static com.google.protobuf.Descriptors.FileDescriptor
1763 | getDescriptor() {
1764 | return descriptor;
1765 | }
1766 | private static com.google.protobuf.Descriptors.FileDescriptor
1767 | descriptor;
1768 | static {
1769 | java.lang.String[] descriptorData = {
1770 | "\n\020doozer-msg.proto\022\006doozer\"\362\001\n\007Request\022\013" +
1771 | "\n\003tag\030\001 \001(\005\022\"\n\004verb\030\002 \001(\0162\024.doozer.Reque" +
1772 | "st.Verb\022\014\n\004path\030\004 \001(\t\022\r\n\005value\030\005 \001(\014\022\021\n\t" +
1773 | "other_tag\030\006 \001(\005\022\016\n\006offset\030\007 \001(\005\022\013\n\003rev\030\t" +
1774 | " \001(\003\"i\n\004Verb\022\007\n\003GET\020\001\022\007\n\003SET\020\002\022\007\n\003DEL\020\003\022" +
1775 | "\007\n\003REV\020\005\022\010\n\004WAIT\020\006\022\007\n\003NOP\020\007\022\010\n\004WALK\020\t\022\n\n" +
1776 | "\006GETDIR\020\016\022\010\n\004STAT\020\020\022\n\n\006ACCESS\020c\"\310\002\n\010Resp" +
1777 | "onse\022\013\n\003tag\030\001 \001(\005\022\r\n\005flags\030\002 \001(\005\022\013\n\003rev\030" +
1778 | "\003 \001(\003\022\014\n\004path\030\005 \001(\t\022\r\n\005value\030\006 \001(\014\022\013\n\003le" +
1779 | "n\030\010 \001(\005\022&\n\010err_code\030d \001(\0162\024.doozer.Respo",
1780 | "nse.Err\022\022\n\nerr_detail\030e \001(\t\"\254\001\n\003Err\022\t\n\005O" +
1781 | "THER\020\177\022\016\n\nTAG_IN_USE\020\001\022\020\n\014UNKNOWN_VERB\020\002" +
1782 | "\022\014\n\010READONLY\020\003\022\014\n\010TOO_LATE\020\004\022\020\n\014REV_MISM" +
1783 | "ATCH\020\005\022\014\n\010BAD_PATH\020\006\022\017\n\013MISSING_ARG\020\007\022\t\n" +
1784 | "\005RANGE\020\010\022\n\n\006NOTDIR\020\024\022\t\n\005ISDIR\020\025\022\t\n\005NOENT" +
1785 | "\020\026"
1786 | };
1787 | com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
1788 | new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
1789 | public com.google.protobuf.ExtensionRegistry assignDescriptors(
1790 | com.google.protobuf.Descriptors.FileDescriptor root) {
1791 | descriptor = root;
1792 | internal_static_doozer_Request_descriptor =
1793 | getDescriptor().getMessageTypes().get(0);
1794 | internal_static_doozer_Request_fieldAccessorTable = new
1795 | com.google.protobuf.GeneratedMessage.FieldAccessorTable(
1796 | internal_static_doozer_Request_descriptor,
1797 | new java.lang.String[] { "Tag", "Verb", "Path", "Value", "OtherTag", "Offset", "Rev", },
1798 | doozer.DoozerMsg.Request.class,
1799 | doozer.DoozerMsg.Request.Builder.class);
1800 | internal_static_doozer_Response_descriptor =
1801 | getDescriptor().getMessageTypes().get(1);
1802 | internal_static_doozer_Response_fieldAccessorTable = new
1803 | com.google.protobuf.GeneratedMessage.FieldAccessorTable(
1804 | internal_static_doozer_Response_descriptor,
1805 | new java.lang.String[] { "Tag", "Flags", "Rev", "Path", "Value", "Len", "ErrCode", "ErrDetail", },
1806 | doozer.DoozerMsg.Response.class,
1807 | doozer.DoozerMsg.Response.Builder.class);
1808 | return null;
1809 | }
1810 | };
1811 | com.google.protobuf.Descriptors.FileDescriptor
1812 | .internalBuildGeneratedFileFrom(descriptorData,
1813 | new com.google.protobuf.Descriptors.FileDescriptor[] {
1814 | }, assigner);
1815 | }
1816 |
1817 | // @@protoc_insertion_point(outer_class_scope)
1818 | }
1819 |
--------------------------------------------------------------------------------
/src/main/protobuf/doozer-msg.proto:
--------------------------------------------------------------------------------
1 | package doozer;
2 |
3 | // see doc/proto.md
4 | message Request {
5 | optional int32 tag = 1;
6 |
7 | enum Verb {
8 | GET = 1;
9 | SET = 2;
10 | DEL = 3;
11 | REV = 5;
12 | WAIT = 6;
13 | NOP = 7;
14 | WALK = 9;
15 | GETDIR = 14;
16 | STAT = 16;
17 | ACCESS = 99;
18 | }
19 | optional Verb verb = 2;
20 |
21 | optional string path = 4;
22 | optional bytes value = 5;
23 | optional int32 other_tag = 6;
24 |
25 | optional int32 offset = 7;
26 |
27 | optional int64 rev = 9;
28 | }
29 |
30 | // see doc/proto.md
31 | message Response {
32 | optional int32 tag = 1;
33 | optional int32 flags = 2;
34 |
35 | optional int64 rev = 3;
36 | optional string path = 5;
37 | optional bytes value = 6;
38 | optional int32 len = 8;
39 |
40 | enum Err {
41 | // don't use value 0
42 | OTHER = 127;
43 | TAG_IN_USE = 1;
44 | UNKNOWN_VERB = 2;
45 | READONLY = 3;
46 | TOO_LATE = 4;
47 | REV_MISMATCH = 5;
48 | BAD_PATH = 6;
49 | MISSING_ARG = 7;
50 | RANGE = 8;
51 | NOTDIR = 20;
52 | ISDIR = 21;
53 | NOENT = 22;
54 | }
55 | optional Err err_code = 100;
56 | optional string err_detail = 101;
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/resources/akka.conf:
--------------------------------------------------------------------------------
1 | akka {
2 | version = "1.1"
3 | time-unit = "seconds"
4 | event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
5 | event-handler-level = "INFO"
6 | }
--------------------------------------------------------------------------------
/src/main/scala/com/force/doozer/flange/DoozerClient.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by IntelliJ IDEA.
3 | * User: sclasen
4 | * Date: 4/21/11
5 | * Time: 4:12 PM
6 | */
7 |
8 | package com.force.doozer.flange
9 |
10 | import doozer.DoozerMsg
11 | import doozer.DoozerMsg.Response.Err
12 | import akka.actor.Actor._
13 | import akka.dispatch.Future
14 | import org.jboss.netty.handler.codec.frame.{LengthFieldBasedFrameDecoder, LengthFieldPrepender}
15 | import collection.mutable.HashMap
16 | import akka.dispatch.CompletableFuture
17 | import akka.config.Supervision._
18 | import annotation.tailrec
19 | import util.matching.Regex
20 |
21 | import akka.event.EventHandler
22 | import akka.actor.{MaximumNumberOfRestartsWithinTimeRangeReached, Actor}
23 | import java.util.concurrent.ThreadFactory
24 | import java.util.concurrent.atomic.AtomicInteger
25 | import java.lang.{RuntimeException, Thread}
26 |
27 |
28 | object DoozerClient {
29 | implicit def stringToByteArray(value: String): Array[Byte] = value.getBytes("UTF-8")
30 |
31 | implicit def byteArrayToString(value: Array[Byte]): String = new String(value, "UTF-8")
32 | }
33 |
34 | trait DoozerClient {
35 |
36 | def get_!(path: String, rev: Long = 0L): GetResponse
37 |
38 | def get(path: String, rev: Long = 0L): Either[ErrorResponse, GetResponse]
39 |
40 | def getAsync(path: String, rev: Long = 0L)(callback: (Either[ErrorResponse, GetResponse] => Unit)): Unit
41 |
42 | def set_!(path: String, value: Array[Byte], rev: Long): SetResponse
43 |
44 | def set(path: String, value: Array[Byte], rev: Long): Either[ErrorResponse, SetResponse]
45 |
46 | def setAsync(path: String, value: Array[Byte], rev: Long)(callback: (Either[ErrorResponse, SetResponse] => Unit)): Unit
47 |
48 | def delete_!(path: String, rev: Long): DeleteResponse
49 |
50 | def delete(path: String, rev: Long): Either[ErrorResponse, DeleteResponse]
51 |
52 | def deleteAsync(path: String, rev: Long)(callback: (Either[ErrorResponse, DeleteResponse] => Unit)): Unit
53 |
54 | def rev_! : RevResponse
55 |
56 | def rev: Either[ErrorResponse, RevResponse]
57 |
58 | def revAsync(callback: (Either[ErrorResponse, RevResponse] => Unit))
59 |
60 | def wait_!(glob: String, rev: Long, waitFor: Long = Long.MaxValue): WaitResponse
61 |
62 | def wait(glob: String, rev: Long, waitFor: Long = Long.MaxValue): Either[ErrorResponse, WaitResponse]
63 |
64 | def waitAsync(glob: String, rev: Long, waitFor: Long = Long.MaxValue)(callback: (Either[ErrorResponse, WaitResponse]) => Unit)
65 |
66 | def stat_!(path: String, rev: Long): StatResponse
67 |
68 | def stat(path: String, rev: Long): Either[ErrorResponse, StatResponse]
69 |
70 | def statAsync(path: String, rev: Long)(callback: (Either[ErrorResponse, StatResponse]) => Unit)
71 |
72 | def getdir(dir: String, rev: Long, offset: Int): Either[ErrorResponse, GetdirResponse]
73 |
74 | def getdir_!(dir: String, rev: Long, offset: Int): GetdirResponse
75 |
76 | def getdirAsync(dir: String, rev: Long, offset: Int)(callback: (Either[ErrorResponse, GetdirResponse]) => Unit)
77 |
78 | def walk(glob: String, rev: Long, offset: Int): Either[ErrorResponse, WalkResponse]
79 |
80 | def walk_!(glob: String, rev: Long, offset: Int): WalkResponse
81 |
82 | def walkAsync(glob: String, rev: Long, offset: Int)(callback: (Either[ErrorResponse, WalkResponse]) => Unit)
83 |
84 | def walk_all(glob: String, rev: Long): Either[ErrorResponse, List[WalkResponse]]
85 |
86 | def getdir_all(dir: String, rev: Long): Either[ErrorResponse, List[GetdirResponse]]
87 |
88 | def walk_all_!(glob: String, rev: Long): List[WalkResponse]
89 |
90 | def getdir_all_!(dir: String, rev: Long): List[GetdirResponse]
91 |
92 | def watch(glob: String, rev: Long, watchFor: Long = Long.MaxValue)(callback: (Either[ErrorResponse, WaitResponse]) => Boolean)
93 |
94 |
95 | }
96 |
97 | object Flange {
98 |
99 | lazy val daemonThreadFactory = new ThreadFactory {
100 | val count = new AtomicInteger(0)
101 |
102 | def newThread(r: Runnable) = {
103 | val t = new Thread(r, "FlangeConnector:" + count.incrementAndGet())
104 | t.setDaemon(true)
105 | t
106 | }
107 | }
108 |
109 | def parseDoozerUri(doozerUri: String): (List[String], String) = {
110 | """^doozer:\?(.*)$""".r.findFirstMatchIn(doozerUri) match {
111 | case Some(m@Regex.Match(_)) => {
112 | val doozerds = for {
113 | caServer <- m.group(1).split("&").toList
114 | k <- caServer.split("=").headOption if k == "ca"
115 | v <- caServer.split("=").tail.headOption
116 | } yield v
117 | val sk = for {
118 | sks <- m.group(1).split("&").toList
119 | k <- sks.split("=").headOption if k == "sk"
120 | v <- sks.split("=").tail.headOption
121 | } yield v
122 |
123 | (doozerds, sk.headOption.getOrElse(throw new IllegalArgumentException("Missing sk param")))
124 | }
125 | case _ => throw new IllegalArgumentException("cant parse doozerUri:" + doozerUri)
126 | }
127 | }
128 |
129 | def eachDoozerOnceStrategy(doozerds: List[String]): Iterable[String] = {
130 | doozerds.toIterable
131 | }
132 |
133 | def retryForeverStrategy(doozerds: List[String]): Iterable[String] = {
134 | var cur = doozerds
135 | Stream.continually {
136 | cur.headOption match {
137 | case Some(doozer) => {
138 | cur = cur.tail
139 | doozer
140 | }
141 | case None => {
142 | cur = doozerds.tail
143 | doozerds.head
144 | }
145 | }
146 | }
147 | }
148 |
149 | val allConnectionsFailed = "ALL_CONNECTIONS_FAILED"
150 | }
151 |
152 |
153 | import Flange._
154 |
155 |
156 | class Flange(doozerUri: String, failoverStrategy: List[String] => Iterable[String] = eachDoozerOnceStrategy) extends DoozerClient {
157 |
158 | private val (doozerds, sk) = parseDoozerUri(doozerUri)
159 | private val supervisor = actorOf(new ConnectionSupervisor(doozerds.size)).start()
160 | private val connection = {
161 | val state = new ClientState(sk, failoverStrategy(doozerds))
162 | val conn = actorOf(new ConnectionActor(state))
163 | supervisor.startLink(conn)
164 | conn
165 | }
166 |
167 | def stop() {
168 | connection.stop()
169 | supervisor.stop()
170 | }
171 |
172 | private def timeout = Left(ErrorResponse("CLIENT_TIMEOUT", "The operation timed out"))
173 |
174 | private def noConnections = Left(ErrorResponse(allConnectionsFailed, "Attempts to retry the operation at all configured servers failed"))
175 |
176 | private def exception(t: Throwable) = Left(ErrorResponse("DoozerClient Exception", t.getStackTraceString))
177 |
178 | private def retry[T](req: DoozerRequest)(success: PartialFunction[Any, Either[ErrorResponse, T]]): Either[ConnectionFailed, Either[ErrorResponse, T]] = {
179 | try {
180 | val resp = connection !! (req, req.timeout)
181 | if (resp.isDefined && success.isDefinedAt(resp.get)) Right(success(resp.get))
182 | else resp match {
183 | case Some(e@ErrorResponse(_, desc)) if desc equals "permission denied" => {
184 | connection !! AccessRequest(sk) match {
185 | case Some(r: AccessResponse) => retry(req)(success)
186 | case er@_ => {
187 | EventHandler.error(er, "cant auth")
188 | Left(ConnectionFailed())
189 | }
190 | }
191 | }
192 | case Some(e@ErrorResponse(_, _)) => Right(Left(e))
193 | case Some(NoConnectionsLeft) => Right(noConnections)
194 | case None => Left(ConnectionFailed())
195 | }
196 | } catch {
197 | case e =>
198 | EventHandler.error(e, this, "error")
199 | Left(ConnectionFailed())
200 | }
201 | }
202 |
203 | @tailrec
204 | private def complete[T](req: DoozerRequest)(success: PartialFunction[Any, Either[ErrorResponse, T]]): Either[ErrorResponse, T] = {
205 | val res = retry[T](req)(success)
206 | res match {
207 | case Right(ok) => ok
208 | case Left(fail) => complete[T](req)(success)
209 | }
210 | }
211 |
212 |
213 | private def completeFuture[T](req: DoozerRequest, responseCallback: (Either[ErrorResponse, T] => Unit))(success: PartialFunction[Any, Either[ErrorResponse, T]]) {
214 | val future: Future[_] = connection !!! (req, req.timeout)
215 | future.asInstanceOf[Future[T]].onComplete {
216 | f: Future[T] =>
217 | if (success.isDefinedAt(f.value)) responseCallback(success(f.value))
218 | else {
219 | f.value match {
220 | case Some(Right(e@ErrorResponse(_, desc))) if desc equals "permission denied" => {
221 | connection !! AccessRequest(sk) match {
222 | case Some(r: AccessResponse) => retry(req)(success)
223 | case er@_ => {
224 | EventHandler.error(er, "cant auth")
225 | responseCallback(Left(e))
226 | }
227 | }
228 | }
229 | case Some(Right(e@ErrorResponse(_, _))) => responseCallback(Left(e))
230 | case Some(Right(NoConnectionsLeft)) => responseCallback(noConnections)
231 | case _ => completeFuture(req, responseCallback)(success)
232 | }
233 | }
234 | }
235 | }
236 |
237 |
238 | def deleteAsync(path: String, rev: Long)(callback: (Either[ErrorResponse, DeleteResponse]) => Unit) {
239 | completeFuture[DeleteResponse](DeleteRequest(path, rev), callback) {
240 | case Some(Right(d@DeleteResponse(_))) => Right(d)
241 | }
242 | }
243 |
244 |
245 | def delete_!(path: String, rev: Long) = delete(path, rev) match {
246 | case Right(d@DeleteResponse(_)) => d
247 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
248 | }
249 |
250 | def delete(path: String, rev: Long) = complete[DeleteResponse](DeleteRequest(path, rev)) {
251 | case d@DeleteResponse(_) => Right(d)
252 | }
253 |
254 | def setAsync(path: String, value: Array[Byte], rev: Long)(callback: (Either[ErrorResponse, SetResponse]) => Unit) {
255 | completeFuture[SetResponse](SetRequest(path, value, rev), callback) {
256 | case Some(Right(s@SetResponse(_))) => Right(s)
257 | }
258 | }
259 |
260 | def set_!(path: String, value: Array[Byte], rev: Long) = set(path, value, rev) match {
261 | case Right(s@SetResponse(_)) => s
262 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
263 | }
264 |
265 | def set(path: String, value: Array[Byte], rev: Long) = complete[SetResponse](SetRequest(path, value, rev)) {
266 | case s@SetResponse(_) => Right(s)
267 | }
268 |
269 | def getAsync(path: String, rev: Long = 0L)(callback: (Either[ErrorResponse, GetResponse]) => Unit) {
270 | completeFuture[GetResponse](GetRequest(path, rev), callback) {
271 | case Some(Right(g@GetResponse(_, _))) => Right(g)
272 | }
273 | }
274 |
275 | def get(path: String, rev: Long = 0L): Either[ErrorResponse, GetResponse] = complete[GetResponse](GetRequest(path, rev)) {
276 | case g@GetResponse(_, _) => Right(g)
277 | }
278 |
279 | def get_!(path: String, rev: Long = 0L) = get(path, rev) match {
280 | case Right(g@GetResponse(_, _)) => g
281 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
282 | }
283 |
284 | def revAsync(callback: (Either[ErrorResponse, RevResponse]) => Unit) {
285 | completeFuture[RevResponse](RevRequest, callback) {
286 | case Some(Right(r@RevResponse(_))) => Right(r)
287 | }
288 | }
289 |
290 | def rev = complete[RevResponse](RevRequest) {
291 | case r@RevResponse(_) => Right(r)
292 | }
293 |
294 | def rev_! = rev match {
295 | case Right(r@RevResponse(_)) => r
296 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
297 | }
298 |
299 | def waitAsync(glob: String, rev: Long, waitFor: Long = Long.MaxValue)(callback: (Either[ErrorResponse, WaitResponse]) => Unit) = {
300 | completeFuture[WaitResponse](WaitRequest(glob, rev, waitFor), callback) {
301 | case Some(Right(w@WaitResponse(_, _, _))) => Right(w)
302 | }
303 | }
304 |
305 | def wait(glob: String, rev: Long, waitFor: Long = Long.MaxValue) = complete[WaitResponse](WaitRequest(glob, rev, waitFor)) {
306 | case w@WaitResponse(_, _, _) => Right(w)
307 | }
308 |
309 | def wait_!(glob: String, rev: Long, waitFor: Long = Long.MaxValue) = wait(glob, rev, waitFor) match {
310 | case Right(w@WaitResponse(_, _, _)) => w
311 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
312 | }
313 |
314 | def statAsync(path: String, rev: Long)(callback: (Either[ErrorResponse, StatResponse]) => Unit) = {
315 | completeFuture[StatResponse](StatRequest(path, rev), callback) {
316 | case Some(Right(s@StatResponse(_, _, _))) => Right(s)
317 | }
318 | }
319 |
320 | def stat(path: String, rev: Long) = complete[StatResponse](StatRequest(path, rev)) {
321 | case s@StatResponse(_, _, _) => Right(s)
322 | }
323 |
324 |
325 | def stat_!(path: String, rev: Long) = stat(path, rev) match {
326 | case Right(s@StatResponse(_, _, _)) => s
327 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
328 | }
329 |
330 | def getdir(dir: String, rev: Long, offset: Int) = complete[GetdirResponse](GetdirRequest(dir, rev, offset)) {
331 | case g@GetdirResponse(_, _) => Right(g)
332 | }
333 |
334 | def getdir_!(dir: String, rev: Long, offset: Int) = getdir(dir, rev, offset) match {
335 | case Right(g@GetdirResponse(_, _)) => g
336 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
337 | }
338 |
339 | def getdirAsync(dir: String, rev: Long, offset: Int)(callback: (Either[ErrorResponse, GetdirResponse]) => Unit) = {
340 | completeFuture[GetdirResponse](GetdirRequest(dir, rev, offset), callback) {
341 | case Some(Right(g@GetdirResponse(_, _))) => Right(g)
342 | }
343 | }
344 |
345 | def walk(glob: String, rev: Long, offset: Int) = complete[WalkResponse](WalkRequest(glob, rev, offset)) {
346 | case w@WalkResponse(_, _, _) => Right(w)
347 | }
348 |
349 | def walk_!(glob: String, rev: Long, offset: Int) = walk(glob, rev, offset) match {
350 | case Right(w@WalkResponse(_, _, _)) => w
351 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
352 | }
353 |
354 | def walkAsync(glob: String, rev: Long, offset: Int)(callback: (Either[ErrorResponse, WalkResponse]) => Unit) = {
355 | completeFuture[WalkResponse](WalkRequest(glob, rev, offset), callback) {
356 | case Some(Right(w@WalkResponse(_, _, _))) => Right(w)
357 | }
358 | }
359 |
360 | def watch(glob: String, rev: Long, waitFor: Long = Long.MaxValue)(callback: (Either[ErrorResponse, WaitResponse]) => Boolean) = {
361 | def inner(r: Long, either: Either[ErrorResponse, WaitResponse]) {
362 | if (callback.apply(either)) {
363 | either match {
364 | case Left(_) => waitAsync(glob, r , waitFor)(inner(r , _))
365 | case Right(WaitResponse(_,_,newRev)) => waitAsync(glob, newRev+1 , waitFor)(inner(newRev+1 , _))
366 | }
367 | }
368 | }
369 | waitAsync(glob, rev, waitFor)(inner(rev, _))
370 | }
371 |
372 | def getdir_all(dir: String, rev: Long) = {
373 | all_internal[GetdirResponse](getdir(dir, rev, _), 0, Nil)
374 | }
375 |
376 | @tailrec
377 | private def all_internal[T](func: Int => Either[ErrorResponse, T], offset: Int, responses: List[T]): Either[ErrorResponse, List[T]] = {
378 | func.apply(offset) match {
379 | case Left(ErrorResponse(code, msg)) if code eq Err.RANGE.name() => Right(responses)
380 | case Left(e@ErrorResponse(_, _)) => Left(e)
381 | case Right(t: T) => all_internal(func, offset + 1, responses :+ t)
382 | }
383 | }
384 |
385 | def walk_all(glob: String, rev: Long) = {
386 | all_internal[WalkResponse](walk(glob, rev, _), 0, Nil)
387 | }
388 |
389 | def getdir_all_!(dir: String, rev: Long) = getdir_all(dir, rev) match {
390 | case Right(responses) => responses
391 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
392 | }
393 |
394 | def walk_all_!(glob: String, rev: Long) = walk_all(glob, rev) match {
395 | case Right(responses) => responses
396 | case Left(e@ErrorResponse(_, _)) => throw new ErrorResponseException(e)
397 | }
398 | }
399 |
400 | class ConnectionSupervisor(numHosts: Int) extends Actor {
401 | self.faultHandler = OneForOneStrategy(List(classOf[Exception]), numHosts, numHosts * 1000)
402 |
403 | protected def receive = {
404 | case MaximumNumberOfRestartsWithinTimeRangeReached(_, _, _, ex) => EventHandler.error(ex, this, "Too Many Restarts")
405 | }
406 | }
407 |
408 | class ClientState(val secret: String, var hosts: Iterable[String], var tag: Int = 0)
409 |
410 | class ConnectionFailedException(val host: String, cause: Throwable) extends RuntimeException(cause)
411 |
412 | class ErrorResponseException(val resp: ErrorResponse) extends RuntimeException()
413 |
414 | import org.jboss.netty.bootstrap.ClientBootstrap
415 | import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory
416 | import org.jboss.netty.channel.Channel
417 | import java.util.concurrent.Executors
418 | import java.net.InetSocketAddress
419 | import com.force.doozer.flange.Flange._
420 |
421 |
422 | class ConnectionActor(state: ClientState) extends Actor {
423 | self.lifeCycle = Permanent
424 |
425 | private var host: String = null
426 | private var port: Int = 0
427 | private var requests = new HashMap[Int, DoozerRequest]
428 | private var responses = new HashMap[Int, Option[CompletableFuture[_]]]
429 | private var connected = false
430 | private var bootstrap: ClientBootstrap = null
431 | private var handler: Handler = null
432 | private var channel: Channel = null
433 |
434 |
435 | state.hosts.headOption match {
436 | case Some(h) => {
437 | host = h.split(":").apply(0)
438 | port = h.split(":").apply(1).toInt
439 | state.hosts = state.hosts.tail
440 | }
441 | case None => {
442 | become(noConn(), false)
443 | }
444 | }
445 |
446 | private def notifyWaiters(ex: Throwable) {
447 | for {
448 | futureOpt <- responses.values
449 | future <- futureOpt
450 | } future.completeWithException(ex)
451 | }
452 |
453 | override def postStop() {
454 | notifyWaiters(new RuntimeException("Connection actor was stopped"))
455 | }
456 |
457 | override def preRestart(reason: Throwable) {
458 | EventHandler.warning(this, "failed:" + host + ":" + port)
459 | try {
460 | if (channel != null) channel.close()
461 | }
462 | catch {
463 | case _ =>
464 | }
465 | try {
466 | if (bootstrap != null) bootstrap.releaseExternalResources()
467 | }
468 | catch {
469 | case _ =>
470 | }
471 | notifyWaiters(reason)
472 | }
473 |
474 |
475 | override def postRestart(reason: Throwable) {
476 | EventHandler.warning(this, "failTo:" + host + ":" + port)
477 | }
478 |
479 | private def noConn(): Receive = {
480 | case _ => self.reply(NoConnectionsLeft)
481 | }
482 |
483 | private def connect() {
484 | bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(
485 | Executors.newCachedThreadPool(daemonThreadFactory),
486 | Executors.newCachedThreadPool(daemonThreadFactory)));
487 | bootstrap.setPipelineFactory(new PipelineFactory());
488 | bootstrap.setOption("tcpNoDelay", true)
489 | bootstrap.setOption("keepAlive", true)
490 | // Make a new connection.
491 | val connectFuture =
492 | bootstrap.connect(new InetSocketAddress(host, port));
493 | // Wait until the connection is made successfully
494 | connectFuture.awaitUninterruptibly()
495 | if (connectFuture.isSuccess) channel = connectFuture.getChannel
496 | else throw new IllegalStateException("Channel didnt connect")
497 | // Get the handler instance to initiate the request.
498 | handler =
499 | channel.getPipeline().get(classOf[Handler])
500 | handler.ref = self
501 | }
502 |
503 | private def doSend(req: DoozerRequest): Unit = {
504 | val currentTag = state.tag
505 | state.tag += 1
506 | requests += currentTag -> req
507 | responses += currentTag -> self.senderFuture
508 | if (!connected) {
509 | connect()
510 | connected = true
511 | }
512 | handler.send(req.toBuilder.setTag(currentTag).build)
513 | }
514 |
515 |
516 | override protected def receive = {
517 | case req: DoozerRequest => doSend(req)
518 | case response: DoozerMsg.Response => {
519 | requests.remove(response.getTag) match {
520 | case Some(req) => {
521 | val msg = DoozerResponse.isOk(response) match {
522 | case true => req.toResponse(response)
523 | case false => req.toError(response)
524 | }
525 | responses.remove(response.getTag) match {
526 | case Some(future) => future.get.asInstanceOf[CompletableFuture[Any]].completeWithResult(msg)
527 | case None => EventHandler.warning(this, "Received a response with tag %d but there was no futute to complete".format(response.getTag))
528 | }
529 | }
530 | case None => EventHandler.warning(this, "Revieved a response with tag %d but there was no request to correlate with".format(response.getTag))
531 | }
532 | }
533 | }
534 |
535 |
536 | }
537 |
538 | import org.jboss.netty.channel._
539 | import akka.actor.ActorRef
540 |
541 | class Handler extends SimpleChannelUpstreamHandler {
542 |
543 | @volatile var ref: ActorRef = null
544 | @volatile var channel: Channel = null
545 |
546 | def send(msg: DoozerMsg.Request) {
547 | EventHandler.debug(this, "====>sent:" + msg.toString)
548 | val future = channel.write(msg)
549 | future.awaitUninterruptibly
550 | }
551 |
552 |
553 | override def exceptionCaught(ctx: ChannelHandlerContext, e: ExceptionEvent) {
554 | EventHandler.error(e.getCause, this, "exceptionCaught")
555 | }
556 |
557 | override def messageReceived(ctx: ChannelHandlerContext, e: MessageEvent) {
558 | EventHandler.debug(this, "===>recieved:" + e.getMessage)
559 | ref ! e.getMessage
560 | }
561 |
562 | override def channelOpen(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
563 | channel = ctx.getChannel
564 | super.channelOpen(ctx, e)
565 | }
566 | }
567 |
568 | import org.jboss.netty.channel.ChannelPipelineFactory
569 | import org.jboss.netty.handler.codec.protobuf._
570 |
571 | class PipelineFactory extends ChannelPipelineFactory {
572 | def getPipeline = {
573 | val p = Channels.pipeline
574 | p.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4))
575 | p.addLast("protobufDecoder", new ProtobufDecoder(DoozerMsg.Response.getDefaultInstance()))
576 | p.addLast("frameEncoder", new LengthFieldPrepender(4))
577 | p.addLast("protobufEncoder", new ProtobufEncoder())
578 | p.addLast("handler", new Handler)
579 | p
580 | }
581 |
582 |
583 | }
584 |
585 |
--------------------------------------------------------------------------------
/src/main/scala/com/force/doozer/flange/Messages.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by IntelliJ IDEA.
3 | * User: sclasen
4 | * Date: 4/22/11
5 | * Time: 2:57 PM
6 | */
7 | package com.force.doozer.flange
8 |
9 | import doozer.DoozerMsg
10 | import doozer.DoozerMsg.Request.Verb
11 | import com.google.protobuf.ByteString
12 | import doozer.DoozerMsg.Response.Err
13 | object DoozerRequest {
14 |
15 | }
16 |
17 | object DoozerResponse {
18 |
19 | val valid = 1
20 | val done = 2
21 | val set = 4
22 | val del = 8
23 |
24 | def isOk(msg: DoozerMsg.Response): Boolean = msg.getErrCode == null || (msg.getErrCode == Err.OTHER && (msg.getErrDetail eq ""))
25 | }
26 |
27 | sealed trait DoozerRequest {
28 | type Response
29 |
30 | def builder = DoozerMsg.Request.newBuilder
31 |
32 | def toBuilder: DoozerMsg.Request.Builder
33 |
34 | def toResponse(res: DoozerMsg.Response): Response
35 |
36 | def toError(res: DoozerMsg.Response): ErrorResponse = ErrorResponse(res.getErrCode.name, res.getErrDetail)
37 |
38 | def timeout = 5000L
39 |
40 | }
41 |
42 | case class ErrorResponse(code: String, description: String)
43 |
44 | case class AccessRequest(secret: String) extends DoozerRequest {
45 | type Response = AccessResponse
46 | lazy val toBuilder = builder.setVerb(Verb.ACCESS).setValue(ByteString.copyFromUtf8(secret))
47 |
48 | def toResponse(res: DoozerMsg.Response): AccessResponse = AccessResponse()
49 | }
50 |
51 | case class AccessResponse()
52 |
53 | case class GetRequest(path: String, rev: Long) extends DoozerRequest {
54 | type Response = GetResponse
55 | lazy val toBuilder = {
56 | val b = builder.setVerb(Verb.GET).setPath(path)
57 | if (rev != 0L) b.setRev(rev)
58 | b
59 | }
60 |
61 | def toResponse(res: DoozerMsg.Response): GetResponse = GetResponse(res.getValue.toByteArray, res.getRev)
62 | }
63 |
64 | case class GetResponse(value: Array[Byte], rev: Long)
65 |
66 | case object RevRequest extends DoozerRequest {
67 | type Response = RevResponse
68 | lazy val toBuilder = builder.setVerb(Verb.REV)
69 |
70 | def toResponse(res: DoozerMsg.Response): RevResponse = RevResponse(res.getRev)
71 | }
72 |
73 | case class RevResponse(rev: Long)
74 |
75 |
76 | case class SetRequest(path: String, body: Array[Byte], rev: Long) extends DoozerRequest {
77 | type Response = SetResponse
78 | lazy val toBuilder = builder.setVerb(Verb.SET).setPath(path).setValue(ByteString.copyFrom(body)).setRev(rev)
79 |
80 | def toResponse(res: DoozerMsg.Response): SetResponse = SetResponse(res.getRev)
81 | }
82 |
83 | case class SetResponse(rev: Long)
84 |
85 |
86 | case class DeleteRequest(path: String, rev: Long) extends DoozerRequest {
87 | type Response = DeleteResponse
88 | lazy val toBuilder = builder.setVerb(Verb.DEL).setPath(path).setRev(rev)
89 |
90 | def toResponse(res: DoozerMsg.Response): DeleteResponse = DeleteResponse(res.getPath)
91 | }
92 |
93 | case class WaitRequest(glob: String, rev: Long, maxWait: Long = Long.MaxValue) extends DoozerRequest {
94 | type Response = WaitResponse
95 | lazy val toBuilder = builder.setVerb(Verb.WAIT).setPath(glob).setRev(rev)
96 |
97 | def toResponse(res: DoozerMsg.Response): WaitResponse = WaitResponse(res.getPath, res.getValue.toByteArray, res.getRev)
98 |
99 | override def timeout = maxWait
100 | }
101 |
102 | case class WaitResponse(path: String, value: Array[Byte], rev: Long)
103 |
104 | case class StatRequest(path: String, rev: Long) extends DoozerRequest {
105 | type Response = StatResponse
106 | lazy val toBuilder = builder.setVerb(Verb.STAT).setPath(path).setRev(rev)
107 |
108 | def toResponse(res: DoozerMsg.Response): StatResponse = StatResponse(res.getPath, res.getLen, res.getRev)
109 | }
110 |
111 | case class StatResponse(path: String, length: Int, rev: Long)
112 |
113 |
114 | case class GetdirRequest(dir: String, rev: Long, offset: Int = 0) extends DoozerRequest {
115 | type Response = GetdirResponse
116 | lazy val toBuilder = builder.setVerb(Verb.GETDIR).setPath(dir).setRev(rev).setOffset(offset)
117 |
118 | def toResponse(res: DoozerMsg.Response): GetdirResponse = GetdirResponse(res.getPath, res.getRev)
119 |
120 | def next() = copy(offset = this.offset + 1)
121 | }
122 |
123 | case class GetdirResponse(path: String, rev: Long)
124 |
125 | case class WalkRequest(path: String, rev: Long, offset: Int = 0) extends DoozerRequest {
126 | type Response = WalkResponse
127 | lazy val toBuilder = builder.setVerb(Verb.WALK).setPath(path).setRev(rev).setOffset(offset)
128 |
129 | def toResponse(res: DoozerMsg.Response): WalkResponse = WalkResponse(res.getPath, res.getValue.toByteArray, res.getRev)
130 | }
131 |
132 | case class WalkResponse(path: String, value: Array[Byte], rev: Long)
133 |
134 | case class DeleteResponse(path: String)
135 |
136 | case class ConnectionFailed()
137 |
138 | case object NoConnectionsLeft
--------------------------------------------------------------------------------
/src/test/scala/com/force/doozer/flange/ClientSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by IntelliJ IDEA.
3 | * User: sclasen
4 | * Date: 4/23/11
5 | * Time: 12:14 PM
6 | */
7 | package com.force.doozer.flange
8 |
9 | import org.scalatest.WordSpec
10 | import org.scalatest.BeforeAndAfterAll
11 | import org.scalatest.matchers.MustMatchers
12 | import akka.actor.Actor._
13 | import com.force.doozer.flange.DoozerClient._
14 |
15 | class ClientSpec extends WordSpec with MustMatchers with BeforeAndAfterAll with Waiting {
16 |
17 | var client: Flange = null
18 | var uri = "doozer:?ca=localhost:12345&ca=localhost:8046&sk=secret"
19 |
20 | "A Doozer Client" must {
21 | "set and get and stat and delete values correctly" in {
22 | System.out.println("Exceptions are to be expected here as we purposely use a url with a host thats not up to test failover")
23 | (1 to 20) foreach {
24 | i => {
25 | val path = "/" + System.currentTimeMillis.toString
26 | val value = path + "--value"
27 | val response: SetResponse = client.set_!(path, value, 0L)
28 | val getResponse: GetResponse = client.get_!(path)
29 | getResponse.value must be(value.getBytes)
30 | client.stat_!(path,getResponse.rev).length must be(getResponse.value.length)
31 | client.delete_!(path, response.rev)
32 | }
33 | }
34 | val path = "/" + System.currentTimeMillis.toString
35 | val value = path + "--value"
36 | val value2 = path + "--value2"
37 | val response: SetResponse = client.set_!(path, value, 0L)
38 | val response2: SetResponse = client.set_!(path, value2, response.rev)
39 | client.getAsync(path)(asyncGet(value2, _))
40 | waitForAsync(1000) must be (true)
41 | client.get_!(path, response.rev).value must be(value.getBytes)
42 | client.get_!(path,response2.rev).value must be(value2.getBytes)
43 | client.delete_!(path, response2.rev)
44 | }
45 |
46 |
47 | "getdir correctly" in{
48 | val path = "/" + System.currentTimeMillis.toString
49 | val a = path + "/a"
50 | val b = path + "/b"
51 | val c = path + "/c"
52 | val resA: SetResponse = client.set_!(a, a, 0)
53 | val resB: SetResponse = client.set_!(b, b, 0)
54 | val resC: SetResponse = client.set_!(c, c, 0)
55 |
56 | client.getdir_!(path, resA.rev, 0).path must be("a")
57 | evaluating {client.getdir_!(path,resA.rev,1)} must produce[ErrorResponseException]
58 |
59 | client.getdir_!(path, resB.rev, 0).path must be("a")
60 | client.getdir_!(path, resB.rev, 1).path must be("b")
61 | evaluating {client.getdir_!(path,resB.rev,2)} must produce[ErrorResponseException]
62 |
63 | client.getdir_!(path, resC.rev, 0).path must be("a")
64 | client.getdir_!(path, resC.rev, 1).path must be("b")
65 | client.getdir_!(path, resC.rev, 2).path must be("c")
66 | evaluating {client.getdir_!(path,resC.rev,3)} must produce[ErrorResponseException]
67 |
68 | client.getdir_all_!(path, resC.rev).map(_.path) must be(List("a","b","c"))
69 | }
70 |
71 | "walk correctly" in{
72 | val path = "/" + System.currentTimeMillis.toString
73 | val pathglob = path + "/*"
74 | val a = path + "/a"
75 | val b = path + "/b"
76 | val c = path + "/c"
77 | val resA: SetResponse = client.set_!(a, a, 0)
78 | val resB: SetResponse = client.set_!(b, b, 0)
79 | val resC: SetResponse = client.set_!(c, c, 0)
80 |
81 | client.walk_!(pathglob, resA.rev, 0).path must be(a)
82 | client.walk_!(pathglob, resA.rev, 0).value must be(a.getBytes)
83 | evaluating {client.walk_!(path,resA.rev,1)} must produce[ErrorResponseException]
84 |
85 | client.walk_!(pathglob, resB.rev, 0).path must be(a)
86 | client.walk_!(pathglob, resB.rev, 1).path must be(b)
87 | client.walk_!(pathglob, resB.rev, 0).value must be(a.getBytes)
88 | client.walk_!(pathglob, resB.rev, 1).value must be(b.getBytes)
89 | evaluating {client.walk_!(path,resB.rev,2)} must produce[ErrorResponseException]
90 |
91 | client.walk_!(pathglob, resC.rev, 0).path must be(a)
92 | client.walk_!(pathglob, resC.rev, 1).path must be(b)
93 | client.walk_!(pathglob, resC.rev, 2).path must be(c)
94 | client.walk_!(pathglob, resC.rev, 0).value must be(a.getBytes)
95 | client.walk_!(pathglob, resC.rev, 1).value must be(b.getBytes)
96 | client.walk_!(pathglob, resC.rev, 2).value must be(c.getBytes)
97 | evaluating {client.walk_!(path,resC.rev,3)} must produce[ErrorResponseException]
98 |
99 | client.walk_all_!(pathglob,resC.rev).map(w=>new String(w.value)) must be(List(a,b,c))
100 | client.walk_all_!(pathglob,resC.rev).map(_.path) must be(List(a,b,c))
101 | }
102 |
103 | "get rev correctly" in {
104 | (client.rev_!.rev) > 0 must be(true)
105 | }
106 |
107 | "wait correctly" in {
108 | reset(1)
109 |
110 | val path1 = "/" + System.currentTimeMillis.toString
111 | Thread.sleep(10)
112 | val path2 = "/" + System.currentTimeMillis.toString
113 |
114 | val response: SetResponse = client.set_!(path1, path1, 0L)
115 | val response2: SetResponse = client.set_!(path2, path2, 0L)
116 |
117 | client.waitAsync(path1, response.rev) {
118 | wr => {
119 | wr match {
120 | case Right(w@WaitResponse(_, value, _)) => {
121 | System.out.println(w.toString)
122 | System.out.println(new String(value))
123 | signalAsyncDone()
124 | }
125 | case Left(ErrorResponse(code, msg)) => System.out.println(code + " " + msg)
126 | }
127 | }
128 | }
129 |
130 | client.waitAsync(path2, response2.rev) {
131 | wr => {
132 | wr match {
133 | case Right(w@WaitResponse(_, value, _)) => {
134 | System.out.println(w.toString)
135 | System.out.println(new String(value))
136 | signalAsyncDone()
137 | }
138 | case Left(ErrorResponse(code, msg)) => System.out.println(code + " " + msg)
139 | }
140 |
141 |
142 | }
143 | }
144 |
145 | var set: SetResponse = client.set_!(path2, path1, response2.rev)
146 | client.set_!(path1, path2, response.rev)
147 |
148 | waitForAsync(10000) must be(true)
149 | System.out.println("DONE")
150 |
151 | reset(2)
152 | client.watch(path2,set.rev){
153 | either=>{
154 | debug(either)
155 | signalAsyncDone()
156 | true
157 | }
158 | }
159 |
160 | set = client.set_!(path2,"foowait1",set.rev)
161 | client.set_!(path2,"foowait2",set.rev)
162 | waitForAsync(10000) must be(true)
163 |
164 | }
165 |
166 |
167 | }
168 |
169 | def asyncGet(value: String, resp: Either[ErrorResponse, GetResponse]) {
170 | resp match {
171 | case Right(GetResponse(respValue, cas)) => {
172 | respValue must be(value.getBytes)
173 | signalAsyncDone()
174 | }
175 | case x@_ => failure(x)
176 | }
177 | }
178 |
179 |
180 | def debug(any: Any) {
181 | System.out.println(any.toString)
182 | }
183 |
184 | def failure(any: Any) {
185 | System.out.println("Error in Async GET")
186 | fail("Bad response")
187 | }
188 |
189 | "Two Clients" must {
190 | "not blow up" in {
191 | val second = new Flange(uri)
192 | second.set("/second", "second" getBytes, 0)
193 | client.get_!("/second").value must be("second".getBytes)
194 | }
195 | }
196 |
197 | override protected def beforeAll(configMap: Map[String, Any]) {
198 | client = new Flange(uri)
199 | }
200 |
201 | override protected def afterAll() {
202 | registry.shutdownAll()
203 | }
204 | }
--------------------------------------------------------------------------------
/src/test/scala/com/force/doozer/flange/ConnectionSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by IntelliJ IDEA.
3 | * User: sclasen
4 | * Date: 4/21/11
5 | * Time: 9:36 PM
6 | */
7 | package com.force.doozer.flange
8 |
9 | import org.scalatest.WordSpec
10 | import org.scalatest.matchers.MustMatchers
11 | import akka.actor.Actor._
12 | import akka.actor.ActorRef
13 | import DoozerRequest._
14 | import Flange._
15 | class ConnectionSpec extends WordSpec with MustMatchers {
16 |
17 |
18 | "a test" must {
19 | "work" in {
20 | var rev = 0L
21 | actorOf(new ConnectionActor(new ClientState("secret",List("localhost:8046").toIterable))).start()
22 | val ref: ActorRef = registry.actorsFor[ConnectionActor].head
23 | ref !! GetRequest("/d/local/foo",rev) match {
24 | case Some(GetResponse(_, curr)) => {
25 | rev = curr
26 | print("got")
27 | }
28 | case Some(e@ErrorResponse(_, _)) => {
29 | print(e)
30 | }
31 | case x@_ => print(x)
32 | }
33 |
34 |
35 |
36 |
37 | ref !! SetRequest("/d/local/foo", ("bar" + rev).getBytes, rev) match {
38 | case Some(SetResponse(cas)) => {
39 | print("Set")
40 | rev = cas
41 | }
42 | case Some(ErrorResponse(code, detail)) => {
43 | print(code)
44 | print(detail)
45 | }
46 | case x@_ => print(x)
47 | }
48 | ref !! SetRequest("/d/local/foo", ("bar" + rev).getBytes, rev) match {
49 | case Some(SetResponse(cas)) => {
50 | print("Set")
51 | rev = cas
52 | }
53 | case Some(ErrorResponse(code, detail)) => {
54 | print(code)
55 | print(detail)
56 | }
57 | case x@_ => print(x)
58 | }
59 |
60 | registry.shutdownAll()
61 | }
62 | }
63 |
64 | def print(any: Any) {
65 | System.out.println("==========>" + any)
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/src/test/scala/com/force/doozer/flange/FailoverSpec.scala:
--------------------------------------------------------------------------------
1 | package com.force.doozer.flange
2 |
3 | /*
4 | * Created by IntelliJ IDEA.
5 | * User: sclasen
6 | * Date: 4/25/11
7 | * Time: 12:21 PM
8 | */
9 |
10 | import org.scalatest.matchers.MustMatchers
11 | import org.scalatest.{BeforeAndAfterAll, WordSpec}
12 | import akka.actor.Actor
13 |
14 | class FailoverSpec extends WordSpec with MustMatchers with BeforeAndAfterAll with Waiting {
15 |
16 | var client: Flange = null
17 |
18 |
19 | "A Doozer DoozerClient" must {
20 | "fail over properly when no servers are up" in {
21 | val clientWithNoServersUp = new Flange("doozer:?ca=localhost:12321&ca=localhost:12322&sk=foo")
22 | try {
23 | clientWithNoServersUp.set("/nothome", "avalue".getBytes, 0L) match {
24 | case Left(ErrorResponse(err, _)) => err must be(Flange.allConnectionsFailed)
25 | case Right(SetResponse(_)) => fail("Set shouldnt success with no server")
26 | }
27 | clientWithNoServersUp.getAsync("/nothome") {
28 | either =>
29 | try {
30 | either match {
31 | case Left(ErrorResponse(err, _)) => {
32 | err must be(Flange.allConnectionsFailed)
33 | }
34 | case Right(GetResponse(_, _)) => fail("get shouldnt success with no server")
35 | }
36 | } finally {
37 | signalAsyncDone()
38 | }
39 | }
40 | waitForAsync()
41 | } catch {
42 | case e => {
43 | signalAsyncDone()
44 | fail(e)
45 | }
46 | } finally {
47 | clientWithNoServersUp.stop
48 | stop()
49 | }
50 | }
51 |
52 |
53 | }
54 |
55 | def stop() {
56 | Actor.registry.shutdownAll()
57 | }
58 |
59 | }
--------------------------------------------------------------------------------
/src/test/scala/com/force/doozer/flange/URISpec.scala:
--------------------------------------------------------------------------------
1 | package com.force.doozer.flange
2 |
3 | /*
4 | * Created by IntelliJ IDEA.
5 | * User: sclasen
6 | * Date: 4/25/11
7 | * Time: 9:51 AM
8 | */
9 |
10 | import org.scalatest.matchers.MustMatchers
11 | import org.scalatest.{BeforeAndAfterAll, WordSpec}
12 |
13 |
14 | class URISpec extends WordSpec with MustMatchers with BeforeAndAfterAll {
15 |
16 | "A Flange" must {
17 | "parse doozer uris correctly" in {
18 | val one = "doozer:?ca=localhost:8046&sk=secret"
19 | Flange.parseDoozerUri(one)._1.headOption must be(Some("localhost:8046"))
20 | val three = "doozer:?ca=localhost:8046&ca=localhost:8047&ca=localhost:8048&sk=secret"
21 | Flange.parseDoozerUri(three)._1 must be(List("localhost:8046","localhost:8047","localhost:8048"))
22 | Flange.parseDoozerUri(three)._2 must be ("secret")
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/src/test/scala/com/force/doozer/flange/Waiting.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by IntelliJ IDEA.
3 | * User: sclasen
4 | * Date: 4/25/11
5 | * Time: 2:01 PM
6 | */
7 | package com.force.doozer.flange
8 |
9 | import java.util.concurrent.{TimeUnit, CountDownLatch}
10 |
11 | trait Waiting {
12 |
13 |
14 | @volatile var latch = new CountDownLatch(1)
15 |
16 | def reset(count: Int) {
17 | while (latch.getCount > 0) latch.countDown()
18 | latch = new CountDownLatch(count)
19 | }
20 |
21 | def waitForAsync() {
22 | latch.await()
23 | }
24 |
25 | def waitForAsync(timeout: Long): Boolean = {
26 | latch.await(timeout, TimeUnit.MILLISECONDS)
27 | }
28 |
29 | def signalAsyncDone() {
30 | latch.countDown()
31 | }
32 | }
--------------------------------------------------------------------------------
/startDoozer.sh:
--------------------------------------------------------------------------------
1 | rm ./doozerd-0.8/dooz.log
2 |
3 | set -e
4 | trap quit INT TERM EXIT
5 |
6 | quit() {
7 | killall doozerd
8 | echo "Unable to successfully start the cluster"
9 | exit
10 | }
11 |
12 | export DOOZER_RWSECRET=secret
13 |
14 | touch ./doozerd-0.8/dooz.log
15 |
16 | OS=linux
17 | UNAME=`uname`
18 | if [ "$UNAME" = "Darwin" ]; then
19 | OS=osx
20 | fi
21 |
22 | ./doozerd-0.8/$OS-386/doozerd -l="127.0.0.1:8046" -w=":8080" >> ./doozerd-0.8/dooz.log 2>&1 &
23 | ./doozerd-0.8/$OS-386/doozerd -l="127.0.0.1:8047" -a="127.0.0.1:8046" -w=":8081" >> ./doozerd-0.8/dooz.log 2>&1 &
24 | ./doozerd-0.8/$OS-386/doozerd -l="127.0.0.1:8048" -a="127.0.0.1:8046" -w=":8082" >> ./doozerd-0.8/dooz.log 2>&1 &
25 |
26 | sleep 1
27 |
28 | printf '' | ./doozerd-0.8/$OS-386/doozer -a "doozer:?ca=127.0.0.1:8046&sk=$DOOZER_RWSECRET" set /ctl/cal/1 0 > /dev/null
29 | printf '' | ./doozerd-0.8/$OS-386/doozer -a "doozer:?ca=127.0.0.1:8046&sk=$DOOZER_RWSECRET" set /ctl/cal/2 0 > /dev/null
30 |
31 |
32 | trap - INT TERM EXIT
33 | echo "Started"
34 |
35 |
36 |
--------------------------------------------------------------------------------
/stopDoozer.sh:
--------------------------------------------------------------------------------
1 | killall doozerd
--------------------------------------------------------------------------------