http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10.java new file mode 100644 index 0000000..5da0797 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import com.google.common.base.Function; +import org.jclouds.chef.domain.CookbookDefinition; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseJson; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Map; +import java.util.Set; + +import static com.google.common.collect.Iterables.transform; +import static com.google.common.collect.Sets.newLinkedHashSet; + +/** + * Parses the cookbook versions in a Chef Server >= 0.10.8. + */ +@Singleton +public class ParseCookbookDefinitionListFromJsonv10 implements Function<HttpResponse, Set<CookbookDefinition>> { + + /** + * Parser for responses from chef server >= 0.10.8 + */ + private final ParseJson<Map<String, CookbookDefinition>> parser; + + @Inject + ParseCookbookDefinitionListFromJsonv10(ParseJson<Map<String, CookbookDefinition>> parser) { + this.parser = parser; + } + + @Override + public Set<CookbookDefinition> apply(HttpResponse response) { + Set<Map.Entry<String, CookbookDefinition>> result = parser.apply(response).entrySet(); + return newLinkedHashSet(transform(result, new Function<Map.Entry<String, CookbookDefinition>, CookbookDefinition>() { + @Override + public CookbookDefinition apply(Map.Entry<String, CookbookDefinition> input) { + String cookbookName = input.getKey(); + CookbookDefinition def = input.getValue(); + return CookbookDefinition.builder() // + .from(def) // + .name(cookbookName) // + .build(); + } + })); + } +}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsCheckingChefVersion.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsCheckingChefVersion.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsCheckingChefVersion.java new file mode 100644 index 0000000..f82a900 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsCheckingChefVersion.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.config.CookbookVersionsParser; +import org.jclouds.http.HttpResponse; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; + +/** + * Parses a cookbook versions from a Json response, taking care of using the + * appropriate parser. + */ +@Singleton +public class ParseCookbookVersionsCheckingChefVersion implements Function<HttpResponse, Set<String>> { + + @VisibleForTesting + final Function<HttpResponse, Set<String>> parser; + + @Inject + ParseCookbookVersionsCheckingChefVersion(@CookbookVersionsParser Function<HttpResponse, Set<String>> parser) { + this.parser = parser; + } + + @Override + public Set<String> apply(HttpResponse response) { + return parser.apply(response); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV09FromJson.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV09FromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV09FromJson.java new file mode 100644 index 0000000..4421b3e --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV09FromJson.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseJson; + +import com.google.common.base.Function; +import static com.google.common.collect.Iterables.getFirst; + +/** + * Parses the cookbook versions in a Chef Server <= 0.9.8. + */ +@Singleton +public class ParseCookbookVersionsV09FromJson implements Function<HttpResponse, Set<String>> { + + private final ParseJson<Map<String, Set<String>>> json; + + @Inject + ParseCookbookVersionsV09FromJson(ParseJson<Map<String, Set<String>>> json) { + this.json = json; + } + + @Override + public Set<String> apply(HttpResponse response) { + return getFirst(json.apply(response).values(), null); + + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV10FromJson.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV10FromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV10FromJson.java new file mode 100644 index 0000000..1a25ac0 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV10FromJson.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.domain.CookbookDefinition; +import org.jclouds.chef.domain.CookbookDefinition.Version; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseJson; + +import com.google.common.base.Function; +import static com.google.common.collect.Iterables.getFirst; +import static com.google.common.collect.Iterables.transform; +import static com.google.common.collect.Sets.newLinkedHashSet; + +/** + * Parses the cookbook versions in a Chef Server >= 0.10.8. + */ +@Singleton +public class ParseCookbookVersionsV10FromJson implements Function<HttpResponse, Set<String>> { + + /** Parser for responses from chef server >= 0.10.8 */ + private final ParseJson<Map<String, CookbookDefinition>> parser; + + @Inject + ParseCookbookVersionsV10FromJson(ParseJson<Map<String, CookbookDefinition>> parser) { + this.parser = parser; + } + + @Override + public Set<String> apply(HttpResponse response) { + CookbookDefinition def = getFirst(parser.apply(response).values(), null); + return newLinkedHashSet(transform(def.getVersions(), new Function<Version, String>() { + @Override + public String apply(Version input) { + return input.getVersion(); + } + })); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseErrorFromJsonOrReturnBody.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseErrorFromJsonOrReturnBody.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseErrorFromJsonOrReturnBody.java new file mode 100644 index 0000000..6440409 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseErrorFromJsonOrReturnBody.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ReturnStringIf2xx; + +import com.google.common.base.Function; + +@Singleton +public class ParseErrorFromJsonOrReturnBody implements Function<HttpResponse, String> { + Pattern pattern = Pattern.compile(".*\\[\"([^\"]+)\"\\].*"); + private final ReturnStringIf2xx returnStringIf200; + + @Inject + ParseErrorFromJsonOrReturnBody(ReturnStringIf2xx returnStringIf200) { + this.returnStringIf200 = returnStringIf200; + } + + @Override + public String apply(HttpResponse response) { + String content = returnStringIf200.apply(response); + if (content == null) + return null; + return parse(content); + } + + public String parse(String in) { + Matcher matcher = pattern.matcher(in); + if (matcher.find()) { + return matcher.group(1); + } + return in; + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseKeySetFromJson.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseKeySetFromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseKeySetFromJson.java new file mode 100644 index 0000000..963c19b --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseKeySetFromJson.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseJson; + +import com.google.common.base.Function; + +@Singleton +public class ParseKeySetFromJson implements Function<HttpResponse, Set<String>> { + + private final ParseJson<Map<String, String>> json; + + @Inject + ParseKeySetFromJson(ParseJson<Map<String, String>> json) { + this.json = json; + } + + @Override + public Set<String> apply(HttpResponse response) { + return json.apply(response).keySet(); + + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchClientsFromJson.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchClientsFromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchClientsFromJson.java new file mode 100644 index 0000000..18ecbfa --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchClientsFromJson.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.domain.Client; +import org.jclouds.http.functions.ParseJson; + +@Singleton +public class ParseSearchClientsFromJson extends ParseSearchResultFromJson<Client> { + + // TODO add generic json parser detector + + @Inject + ParseSearchClientsFromJson(ParseJson<Response<Client>> json) { + super(json); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchDatabagFromJson.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchDatabagFromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchDatabagFromJson.java new file mode 100644 index 0000000..c2c58ef --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchDatabagFromJson.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.domain.DatabagItem; +import org.jclouds.chef.domain.SearchResult; +import org.jclouds.domain.JsonBall; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; + +import com.google.common.base.Function; +import com.google.gson.annotations.SerializedName; +import static com.google.common.collect.Iterables.transform; + +/** + * Parses the search result into a {@link DatabagItem} object. + * <p> + * When searching databags, the items are contained inside the + * <code>raw_data</code> list. + */ +@Singleton +public class ParseSearchDatabagFromJson implements Function<HttpResponse, SearchResult<DatabagItem>> { + + private final ParseJson<Response> responseParser; + + private final Json json; + + static class Row { + @SerializedName("raw_data") + JsonBall rawData; + } + + static class Response { + long start; + List<Row> rows; + } + + @Inject + ParseSearchDatabagFromJson(ParseJson<Response> responseParser, Json json) { + this.responseParser = responseParser; + this.json = json; + } + + @Override + public SearchResult<DatabagItem> apply(HttpResponse response) { + Response returnVal = responseParser.apply(response); + Iterable<DatabagItem> items = transform(returnVal.rows, new Function<Row, DatabagItem>() { + @Override + public DatabagItem apply(Row input) { + return json.fromJson(input.rawData.toString(), DatabagItem.class); + } + }); + + return new SearchResult<DatabagItem>(returnVal.start, items); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchEnvironmentsFromJson.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchEnvironmentsFromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchEnvironmentsFromJson.java new file mode 100644 index 0000000..852e0f3 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchEnvironmentsFromJson.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import org.jclouds.chef.domain.Environment; +import org.jclouds.http.functions.ParseJson; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class ParseSearchEnvironmentsFromJson extends ParseSearchResultFromJson<Environment> { + + // TODO add generic json parser detector + + @Inject + ParseSearchEnvironmentsFromJson(ParseJson<Response<Environment>> json) { + super(json); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchNodesFromJson.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchNodesFromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchNodesFromJson.java new file mode 100644 index 0000000..6d34575 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchNodesFromJson.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.domain.Node; +import org.jclouds.http.functions.ParseJson; + +@Singleton +public class ParseSearchNodesFromJson extends ParseSearchResultFromJson<Node> { + + // TODO add generic json parser detector + + @Inject + ParseSearchNodesFromJson(ParseJson<Response<Node>> json) { + super(json); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchResultFromJson.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchResultFromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchResultFromJson.java new file mode 100644 index 0000000..6c9bd84 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchResultFromJson.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.domain.SearchResult; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseJson; + +import com.google.common.base.Function; + +@Singleton +public class ParseSearchResultFromJson<T> implements Function<HttpResponse, SearchResult<T>> { + + private final ParseJson<Response<T>> json; + + static class Response<T> { + long start; + List<T> rows; + } + + @Inject + ParseSearchResultFromJson(ParseJson<Response<T>> json) { + this.json = json; + } + + @Override + public SearchResult<T> apply(HttpResponse response) { + Response<T> returnVal = json.apply(response); + return new SearchResult<T>(returnVal.start, returnVal.rows); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchRolesFromJson.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchRolesFromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchRolesFromJson.java new file mode 100644 index 0000000..42ba797 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseSearchRolesFromJson.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.domain.Role; +import org.jclouds.http.functions.ParseJson; + +@Singleton +public class ParseSearchRolesFromJson extends ParseSearchResultFromJson<Role> { + + // TODO add generic json parser detector + + @Inject + ParseSearchRolesFromJson(ParseJson<Response<Role>> json) { + super(json); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/RunListForGroup.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/RunListForGroup.java b/apis/chef/src/main/java/org/jclouds/chef/functions/RunListForGroup.java new file mode 100644 index 0000000..b14ae71 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/RunListForGroup.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.domain.DatabagItem; +import org.jclouds.domain.JsonBall; +import org.jclouds.json.Json; + +import com.google.common.base.Function; +import com.google.inject.TypeLiteral; + +/** + * Retrieves the run-list for a specific group + */ +@Singleton +public class RunListForGroup implements Function<String, List<String>> { + public static final Type RUN_LIST_TYPE = new TypeLiteral<List<String>>() { + }.getType(); + private final BootstrapConfigForGroup bootstrapConfigForGroup; + + private final Json json; + + @Inject + public RunListForGroup(BootstrapConfigForGroup bootstrapConfigForGroup, Json json) { + this.bootstrapConfigForGroup = checkNotNull(bootstrapConfigForGroup, "bootstrapConfigForGroup"); + this.json = checkNotNull(json, "json"); + } + + @Override + public List<String> apply(String from) { + DatabagItem bootstrapConfig = bootstrapConfigForGroup.apply(from); + Map<String, JsonBall> config = json.fromJson(bootstrapConfig.toString(), + BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE); + JsonBall runlist = config.get("run_list"); + return json.fromJson(runlist.toString(), RUN_LIST_TYPE); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/functions/UriForResource.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/UriForResource.java b/apis/chef/src/main/java/org/jclouds/chef/functions/UriForResource.java new file mode 100644 index 0000000..d5d0810 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/UriForResource.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.functions; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; + +import javax.inject.Singleton; + +import org.jclouds.chef.domain.Resource; + +import com.google.common.base.Function; + +/** + * Extracts the uri field of the given {@link Resource}. + */ +@Singleton +public class UriForResource implements Function<Object, URI> { + + @Override + public URI apply(Object input) { + checkArgument(checkNotNull(input, "input") instanceof Resource, + "This function can only be applied to Resource objects"); + return ((Resource) input).getUrl(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefApiErrorRetryHandler.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefApiErrorRetryHandler.java b/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefApiErrorRetryHandler.java new file mode 100644 index 0000000..3b4da4a --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefApiErrorRetryHandler.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.handlers; + +import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream; + +import javax.annotation.Resource; +import javax.inject.Named; + +import org.jclouds.Constants; +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.HttpRetryHandler; +import org.jclouds.http.handlers.BackoffLimitedRetryHandler; +import org.jclouds.logging.Logger; + +import com.google.inject.Inject; + +/** + * Allow for eventual consistency on sandbox requests. + */ +public class ChefApiErrorRetryHandler implements HttpRetryHandler { + + @Inject(optional = true) + @Named(Constants.PROPERTY_MAX_RETRIES) + private int retryCountLimit = 5; + + @Resource + protected Logger logger = Logger.NULL; + + private final BackoffLimitedRetryHandler backoffLimitedRetryHandler; + + @Inject + ChefApiErrorRetryHandler(BackoffLimitedRetryHandler backoffLimitedRetryHandler) { + this.backoffLimitedRetryHandler = backoffLimitedRetryHandler; + } + + public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) { + if (command.getFailureCount() > retryCountLimit) + return false; + if (response.getStatusCode() == 400 && command.getCurrentRequest().getMethod().equals("PUT") + && command.getCurrentRequest().getEndpoint().getPath().indexOf("sandboxes") != -1) { + if (response.getPayload() != null) { + String error = new String(closeClientButKeepContentStream(response)); + if (error != null && error.indexOf("was not uploaded") != -1) { + return backoffLimitedRetryHandler.shouldRetryRequest(command, response); + } + } + } + return false; + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefErrorHandler.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefErrorHandler.java b/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefErrorHandler.java new file mode 100644 index 0000000..3376219 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefErrorHandler.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.handlers; + +import static com.google.common.base.Throwables.propagate; + +import java.io.IOException; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.chef.functions.ParseErrorFromJsonOrReturnBody; +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.HttpResponseException; +import org.jclouds.logging.Logger; +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.ResourceNotFoundException; + +import com.google.common.io.Closeables; + +/** + * This will parse and set an appropriate exception on the command object. + */ +@Singleton +public class ChefErrorHandler implements HttpErrorHandler { + @Resource + protected Logger logger = Logger.NULL; + private final ParseErrorFromJsonOrReturnBody errorParser; + + @Inject + ChefErrorHandler(ParseErrorFromJsonOrReturnBody errorParser) { + this.errorParser = errorParser; + } + + public void handleError(HttpCommand command, HttpResponse response) { + String message = errorParser.apply(response); + Exception exception = new HttpResponseException(command, response, message); + try { + message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(), + response.getStatusLine()); + switch (response.getStatusCode()) { + case 401: + case 403: + exception = new AuthorizationException(message, exception); + break; + case 404: + if (!command.getCurrentRequest().getMethod().equals("DELETE")) { + exception = new ResourceNotFoundException(message, exception); + } + break; + } + } finally { + if (response.getPayload() != null) { + try { + Closeables.close(response.getPayload().getInput(), true); + } catch (IOException e) { + throw propagate(e); + } + } + command.setException(exception); + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java b/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java new file mode 100644 index 0000000..d390555 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java @@ -0,0 +1,299 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.internal; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.config.ChefProperties.CHEF_BOOTSTRAP_DATABAG; + +import java.io.IOException; +import java.io.InputStream; +import java.security.PrivateKey; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.ChefContext; +import org.jclouds.chef.ChefService; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.BootstrapConfig; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.domain.DatabagItem; +import org.jclouds.chef.domain.Environment; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.functions.BootstrapConfigForGroup; +import org.jclouds.chef.functions.GroupToBootScript; +import org.jclouds.chef.functions.RunListForGroup; +import org.jclouds.chef.strategy.CleanupStaleNodesAndClients; +import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes; +import org.jclouds.chef.strategy.DeleteAllClientsInList; +import org.jclouds.chef.strategy.DeleteAllNodesInList; +import org.jclouds.chef.strategy.ListClients; +import org.jclouds.chef.strategy.ListCookbookVersions; +import org.jclouds.chef.strategy.ListCookbookVersionsInEnvironment; +import org.jclouds.chef.strategy.ListEnvironments; +import org.jclouds.chef.strategy.ListNodes; +import org.jclouds.chef.strategy.ListNodesInEnvironment; +import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode; +import org.jclouds.crypto.Crypto; +import org.jclouds.domain.JsonBall; +import org.jclouds.io.Payloads; +import org.jclouds.io.payloads.RSADecryptingPayload; +import org.jclouds.io.payloads.RSAEncryptingPayload; +import org.jclouds.json.Json; +import org.jclouds.logging.Logger; +import org.jclouds.scriptbuilder.domain.Statement; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Supplier; +import com.google.common.collect.Maps; +import com.google.common.io.ByteStreams; +import com.google.common.io.InputSupplier; + +@Singleton +public class BaseChefService implements ChefService { + + private final ChefContext chefContext; + private final ChefApi api; + private final CleanupStaleNodesAndClients cleanupStaleNodesAndClients; + private final CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes; + private final DeleteAllNodesInList deleteAllNodesInList; + private final ListNodes listNodes; + private final DeleteAllClientsInList deleteAllClientsInList; + private final ListClients listClients; + private final UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode; + private final Supplier<PrivateKey> privateKey; + private final GroupToBootScript groupToBootScript; + private final String databag; + private final BootstrapConfigForGroup bootstrapConfigForGroup; + private final RunListForGroup runListForGroup; + private final ListCookbookVersions listCookbookVersions; + private final ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment; + private final ListEnvironments listEnvironments; + private final ListNodesInEnvironment listNodesInEnvironment; + private final Json json; + private final Crypto crypto; + + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + protected BaseChefService(ChefContext chefContext, ChefApi api, + CleanupStaleNodesAndClients cleanupStaleNodesAndClients, + CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes, + DeleteAllNodesInList deleteAllNodesInList, ListNodes listNodes, DeleteAllClientsInList deleteAllClientsInList, + ListClients listClients, ListCookbookVersions listCookbookVersions, + UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Supplier<PrivateKey> privateKey, + @Named(CHEF_BOOTSTRAP_DATABAG) String databag, GroupToBootScript groupToBootScript, + BootstrapConfigForGroup bootstrapConfigForGroup, RunListForGroup runListForGroup, + ListEnvironments listEnvironments, ListNodesInEnvironment listNodesInEnvironment, + ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment, Json json, Crypto crypto) { + this.chefContext = checkNotNull(chefContext, "chefContext"); + this.api = checkNotNull(api, "api"); + this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients"); + this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes, + "createNodeAndPopulateAutomaticAttributes"); + this.deleteAllNodesInList = checkNotNull(deleteAllNodesInList, "deleteAllNodesInList"); + this.listNodes = checkNotNull(listNodes, "listNodes"); + this.deleteAllClientsInList = checkNotNull(deleteAllClientsInList, "deleteAllClientsInList"); + this.listClients = checkNotNull(listClients, "listClients"); + this.listCookbookVersions = checkNotNull(listCookbookVersions, "listCookbookVersions"); + this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode, + "updateAutomaticAttributesOnNode"); + this.privateKey = checkNotNull(privateKey, "privateKey"); + this.groupToBootScript = checkNotNull(groupToBootScript, "groupToBootScript"); + this.databag = checkNotNull(databag, "databag"); + this.bootstrapConfigForGroup = checkNotNull(bootstrapConfigForGroup, "bootstrapConfigForGroup"); + this.runListForGroup = checkNotNull(runListForGroup, "runListForGroup"); + this.listEnvironments = checkNotNull(listEnvironments, "listEnvironments"); + this.listNodesInEnvironment = checkNotNull(listNodesInEnvironment, "listNodesInEnvironment"); + this.listCookbookVersionsInEnvironment = checkNotNull(listCookbookVersionsInEnvironment,"listCookbookVersionsInEnvironment"); + this.json = checkNotNull(json, "json"); + this.crypto = checkNotNull(crypto, "crypto"); + } + + @Override + public ChefContext getContext() { + return chefContext; + } + + @Override + public byte[] encrypt(InputSupplier<? extends InputStream> supplier) throws IOException { + return ByteStreams.toByteArray(new RSAEncryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey + .get())); + } + + @Override + public byte[] decrypt(InputSupplier<? extends InputStream> supplier) throws IOException { + return ByteStreams.toByteArray(new RSADecryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey + .get())); + } + + @VisibleForTesting + String buildBootstrapConfiguration(BootstrapConfig bootstrapConfig) { + checkNotNull(bootstrapConfig, "bootstrapConfig must not be null"); + + Map<String, Object> configMap = Maps.newHashMap(); + configMap.put("run_list", bootstrapConfig.getRunList()); + + if (bootstrapConfig.getEnvironment().isPresent()) { + configMap.put("environment", bootstrapConfig.getEnvironment().get()); + } + + if (bootstrapConfig.getAttribtues().isPresent()) { + Map<String, Object> attributes = json.fromJson(bootstrapConfig.getAttribtues().get().toString(), + BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE); + configMap.putAll(attributes); + } + + return json.toJson(configMap); + } + + @Override + public Statement createBootstrapScriptForGroup(String group) { + return groupToBootScript.apply(group); + } + + @Override + public void updateBootstrapConfigForGroup(String group, BootstrapConfig bootstrapConfig) { + try { + api.createDatabag(databag); + } catch (IllegalStateException e) { + + } + + String jsonConfig = buildBootstrapConfiguration(bootstrapConfig); + DatabagItem runlist = new DatabagItem(group, jsonConfig); + + if (api.getDatabagItem(databag, group) == null) { + api.createDatabagItem(databag, runlist); + } else { + api.updateDatabagItem(databag, runlist); + } + } + + @Override + public List<String> getRunListForGroup(String group) { + return runListForGroup.apply(group); + } + + @Override + public JsonBall getBootstrapConfigForGroup(String group) { + return bootstrapConfigForGroup.apply(group); + } + + @Override + public void cleanupStaleNodesAndClients(String prefix, int secondsStale) { + cleanupStaleNodesAndClients.execute(prefix, secondsStale); + } + + @Override + public Node createNodeAndPopulateAutomaticAttributes(String nodeName, Iterable<String> runList) { + return createNodeAndPopulateAutomaticAttributes.execute(nodeName, runList); + } + + @Override + public void updateAutomaticAttributesOnNode(String nodeName) { + updateAutomaticAttributesOnNode.execute(nodeName); + } + + @Override + public void deleteAllNodesInList(Iterable<String> names) { + deleteAllNodesInList.execute(names); + } + + @Override + public void deleteAllClientsInList(Iterable<String> names) { + deleteAllClientsInList.execute(names); + } + + @Override + public Iterable<? extends Node> listNodes() { + return listNodes.execute(); + } + + @Override + public Iterable<? extends Node> listNodes(ExecutorService executorService) { + return listNodes.execute(executorService); + } + + @Override + public Iterable<? extends Client> listClients() { + return listClients.execute(); + } + + @Override + public Iterable<? extends Client> listClients(ExecutorService executorService) { + return listClients.execute(executorService); + } + + @Override + public Iterable<? extends CookbookVersion> listCookbookVersions() { + return listCookbookVersions.execute(); + } + + @Override public Iterable<? extends CookbookVersion> listCookbookVersions( + ExecutorService executorService) { + return listCookbookVersions.execute(executorService); + } + + @Override + public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName) { + return listCookbookVersionsInEnvironment.execute(environmentName); + } + + @Override + public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName, + ExecutorService executorService) { + return listCookbookVersionsInEnvironment.execute(executorService, environmentName); + } + + @Override + public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName, + String numVersions) { + return listCookbookVersionsInEnvironment.execute(environmentName, numVersions); + } + + @Override + public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName, + String numVersions, ExecutorService executorService) { + return listCookbookVersionsInEnvironment.execute(executorService, environmentName, numVersions); + } + + @Override + public Iterable<? extends Environment> listEnvironments() { + return listEnvironments.execute(); + } + + @Override + public Iterable<? extends Node> listNodesInEnvironment(String environmentName) { + return listNodesInEnvironment.execute(environmentName); + } + + @Override + public Iterable<? extends Node> listNodesInEnvironment(String environmentName, ExecutorService executorService) { + return listNodesInEnvironment.execute(executorService, environmentName); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java b/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java new file mode 100644 index 0000000..8aef880 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.IOException; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.Context; +import org.jclouds.chef.ChefContext; +import org.jclouds.chef.ChefService; +import org.jclouds.internal.BaseView; +import org.jclouds.location.Provider; + +import com.google.common.reflect.TypeToken; + +@Singleton +public class ChefContextImpl extends BaseView implements ChefContext { + private final ChefService chefService; + + @Inject + protected ChefContextImpl(@Provider Context backend, @Provider TypeToken<? extends Context> backendType, + ChefService chefService) { + super(backend, backendType); + this.chefService = checkNotNull(chefService, "chefService"); + } + + @Override + public ChefService getChefService() { + return chefService; + } + + @Override + public void close() throws IOException { + delegate().close(); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/options/CreateClientOptions.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/options/CreateClientOptions.java b/apis/chef/src/main/java/org/jclouds/chef/options/CreateClientOptions.java new file mode 100644 index 0000000..776d7bb --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/options/CreateClientOptions.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.options; + +/** + * Options for the create client method. + */ +public class CreateClientOptions implements Cloneable { + /** Administrator flag. This flag will be ignored in Opscode Hosted Chef. */ + private boolean admin; + + public CreateClientOptions() { + } + + CreateClientOptions(final boolean admin) { + super(); + this.admin = admin; + } + + public boolean isAdmin() { + return admin; + } + + public CreateClientOptions admin() { + this.admin = true; + return this; + } + + @Override + protected Object clone() throws CloneNotSupportedException { + return new CreateClientOptions(admin); + } + + @Override + public String toString() { + return "[admin=" + admin + "]"; + } + + public static class Builder { + /** + * @see CreateClientOptions#admin() + */ + public static CreateClientOptions admin() { + CreateClientOptions options = new CreateClientOptions(); + return options.admin(); + } + + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/options/SearchOptions.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/options/SearchOptions.java b/apis/chef/src/main/java/org/jclouds/chef/options/SearchOptions.java new file mode 100644 index 0000000..cbc1d54 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/options/SearchOptions.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.options; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.http.options.BaseHttpRequestOptions; + +/** + * Options for the search api. + */ +public class SearchOptions extends BaseHttpRequestOptions { + + /** + * A valid search string. + */ + public SearchOptions query(String query) { + this.queryParameters.put("q", checkNotNull(query, "query")); + return this; + } + + /** + * A sort string, such as 'name DESC'. + */ + public SearchOptions sort(String sort) { + this.queryParameters.put("sort", checkNotNull(sort, "sort")); + return this; + } + + /** + * The number of rows to return. + */ + public SearchOptions rows(int rows) { + this.queryParameters.put("rows", String.valueOf(rows)); + return this; + } + + /** + * The result number to start from. + */ + public SearchOptions start(int start) { + this.queryParameters.put("start", String.valueOf(start)); + return this; + } + + public static class Builder { + + /** + * @see SearchOptions#query(String) + */ + public static SearchOptions query(String query) { + SearchOptions options = new SearchOptions(); + return options.query(query); + } + + /** + * @see SearchOptions#sort(String) + */ + public static SearchOptions start(String start) { + SearchOptions options = new SearchOptions(); + return options.sort(start); + } + + /** + * @see SearchOptions#rows(int) + */ + public static SearchOptions rows(int rows) { + SearchOptions options = new SearchOptions(); + return options.rows(rows); + } + + /** + * @see SearchOptions#start(int) + */ + public static SearchOptions start(int start) { + SearchOptions options = new SearchOptions(); + return options.start(start); + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/predicates/CookbookVersionPredicates.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/predicates/CookbookVersionPredicates.java b/apis/chef/src/main/java/org/jclouds/chef/predicates/CookbookVersionPredicates.java new file mode 100644 index 0000000..7edbcae --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/predicates/CookbookVersionPredicates.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.predicates; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Iterables.get; + +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.domain.Resource; + +import com.google.common.base.Predicate; +import com.google.common.base.Splitter; +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.Multimap; + +/** + * Container for cookbook filters (predicates). + * + * This class has static methods that create customized predicates to use with + * {@link org.jclouds.chef.ChefService}. + */ +public class CookbookVersionPredicates { + /** + * @see #containsRecipes + */ + public static Predicate<CookbookVersion> containsRecipe(String recipe) { + return containsRecipes(checkNotNull(recipe, "recipe must be defined")); + } + + /** + * Note that the default recipe of a cookbook is its name. Otherwise, you + * prefix the recipe with the name of the cookbook. ex. {@code apache2} will + * be the default recipe where {@code apache2::mod_proxy} is a specific one + * in the cookbook. + * + * @param recipes + * names of the recipes. + * @return true if the cookbook version contains a recipe in the list. + */ + public static Predicate<CookbookVersion> containsRecipes(String... recipes) { + checkNotNull(recipes, "recipes must be defined"); + final Multimap<String, String> search = LinkedListMultimap.create(); + for (String recipe : recipes) { + if (recipe.indexOf("::") != -1) { + Iterable<String> nameRecipe = Splitter.on("::").split(recipe); + search.put(get(nameRecipe, 0), get(nameRecipe, 1) + ".rb"); + } else { + search.put(recipe, "default.rb"); + } + } + return new Predicate<CookbookVersion>() { + @Override + public boolean apply(final CookbookVersion cookbookVersion) { + return search.containsKey(cookbookVersion.getCookbookName()) + && any(search.get(cookbookVersion.getCookbookName()), new Predicate<String>() { + + @Override + public boolean apply(final String recipeName) { + return any(cookbookVersion.getRecipes(), new Predicate<Resource>() { + + @Override + public boolean apply(Resource resource) { + return resource.getName().equals(recipeName); + } + + }); + } + + }); + } + + @Override + public String toString() { + return "containsRecipes(" + search + ")"; + } + }; + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/CleanupStaleNodesAndClients.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/CleanupStaleNodesAndClients.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/CleanupStaleNodesAndClients.java new file mode 100644 index 0000000..8519450 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/CleanupStaleNodesAndClients.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import org.jclouds.chef.strategy.internal.CleanupStaleNodesAndClientsImpl; + +import com.google.inject.ImplementedBy; + +/** + * + * Cleans up nodes and clients who have been hanging around too long. + */ +@ImplementedBy(CleanupStaleNodesAndClientsImpl.class) +public interface CleanupStaleNodesAndClients { + + void execute(String prefix, int secondsStale); + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/CreateNodeAndPopulateAutomaticAttributes.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/CreateNodeAndPopulateAutomaticAttributes.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/CreateNodeAndPopulateAutomaticAttributes.java new file mode 100644 index 0000000..249be48 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/CreateNodeAndPopulateAutomaticAttributes.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.strategy.internal.CreateNodeAndPopulateAutomaticAttributesImpl; + +import com.google.inject.ImplementedBy; + +/** + * + * Creates a new node with automatic attributes. + */ +@ImplementedBy(CreateNodeAndPopulateAutomaticAttributesImpl.class) +public interface CreateNodeAndPopulateAutomaticAttributes { + Node execute(Node node); + + Node execute(String nodeName, Iterable<String> runList); +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsInList.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsInList.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsInList.java new file mode 100644 index 0000000..7dd7b89 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsInList.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import org.jclouds.chef.strategy.internal.DeleteAllClientsInListImpl; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.ImplementedBy; + +/** + * Deletes all clients in a given list. + */ +@ImplementedBy(DeleteAllClientsInListImpl.class) +public interface DeleteAllClientsInList { + + void execute(Iterable<String> names); + + void execute(ListeningExecutorService executor, Iterable<String> names); + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllNodesInList.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllNodesInList.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllNodesInList.java new file mode 100644 index 0000000..8867e49 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllNodesInList.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import org.jclouds.chef.strategy.internal.DeleteAllNodesInListImpl; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.ImplementedBy; + +@ImplementedBy(DeleteAllNodesInListImpl.class) +public interface DeleteAllNodesInList { + + void execute(Iterable<String> names); + + void execute(ListeningExecutorService executor, Iterable<String> names); + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/ListClients.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/ListClients.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListClients.java new file mode 100644 index 0000000..aa40c2a --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListClients.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import com.google.inject.ImplementedBy; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.strategy.internal.ListClientsImpl; + +import java.util.concurrent.ExecutorService; + +@ImplementedBy(ListClientsImpl.class) +public interface ListClients { + + Iterable<? extends Client> execute(); + + Iterable<? extends Client> execute(ExecutorService executor); + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersions.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersions.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersions.java new file mode 100644 index 0000000..45663a3 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersions.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import com.google.inject.ImplementedBy; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.strategy.internal.ListCookbookVersionsImpl; + +import java.util.concurrent.ExecutorService; + +@ImplementedBy(ListCookbookVersionsImpl.class) +public interface ListCookbookVersions { + + Iterable<? extends CookbookVersion> execute(); + + Iterable<? extends CookbookVersion> execute(ExecutorService executor); + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersionsInEnvironment.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersionsInEnvironment.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersionsInEnvironment.java new file mode 100644 index 0000000..188d29f --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersionsInEnvironment.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import com.google.inject.ImplementedBy; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.strategy.internal.ListCookbookVersionsInEnvironmentImpl; + +import java.util.concurrent.ExecutorService; + +@ImplementedBy(ListCookbookVersionsInEnvironmentImpl.class) +public interface ListCookbookVersionsInEnvironment { + + Iterable<? extends CookbookVersion> execute(String environmentName); + + Iterable<? extends CookbookVersion> execute(String environmentName, String numVersions); + + Iterable<? extends CookbookVersion> execute(ExecutorService executor, String environmentName); + + Iterable<? extends CookbookVersion> execute(ExecutorService executor, String environmentName, String numVersions); + + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/ListEnvironments.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/ListEnvironments.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListEnvironments.java new file mode 100644 index 0000000..553e8d4 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListEnvironments.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import com.google.inject.ImplementedBy; +import org.jclouds.chef.domain.Environment; +import org.jclouds.chef.strategy.internal.ListEnvironmentsImpl; + +import java.util.concurrent.ExecutorService; + +@ImplementedBy(ListEnvironmentsImpl.class) +public interface ListEnvironments { + + Iterable<? extends Environment> execute(); + + Iterable<? extends Environment> execute(ExecutorService executor); +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/ListNodes.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/ListNodes.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListNodes.java new file mode 100644 index 0000000..660eed0 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListNodes.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import com.google.inject.ImplementedBy; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.strategy.internal.ListNodesImpl; + +import java.util.concurrent.ExecutorService; + +@ImplementedBy(ListNodesImpl.class) +public interface ListNodes { + + Iterable<? extends Node> execute(); + + Iterable<? extends Node> execute(ExecutorService executor); + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/ListNodesInEnvironment.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/ListNodesInEnvironment.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListNodesInEnvironment.java new file mode 100644 index 0000000..efeffe6 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListNodesInEnvironment.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import com.google.inject.ImplementedBy; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.strategy.internal.ListNodesInEnvironmentImpl; + +import java.util.concurrent.ExecutorService; + +@ImplementedBy(ListNodesInEnvironmentImpl.class) +public interface ListNodesInEnvironment { + + Iterable<? extends Node> execute(String environmentName); + + Iterable<? extends Node> execute(ExecutorService executor, String environmentName); + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/UpdateAutomaticAttributesOnNode.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/UpdateAutomaticAttributesOnNode.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/UpdateAutomaticAttributesOnNode.java new file mode 100644 index 0000000..0dcb81e --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/UpdateAutomaticAttributesOnNode.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy; + +import org.jclouds.chef.strategy.internal.UpdateAutomaticAttributesOnNodeImpl; + +import com.google.inject.ImplementedBy; + +/** + * + * Updates node with new automatic attributes. + */ +@ImplementedBy(UpdateAutomaticAttributesOnNodeImpl.class) +public interface UpdateAutomaticAttributesOnNode { + + void execute(String nodeName); +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/BaseListCookbookVersionsImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/BaseListCookbookVersionsImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/BaseListCookbookVersionsImpl.java new file mode 100644 index 0000000..94cf79a --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/BaseListCookbookVersionsImpl.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.strategy.internal; + +import com.google.common.base.Function; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.logging.Logger; + +import java.util.List; +import java.util.Set; +import java.util.concurrent.Callable; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Iterables.transform; +import static com.google.common.util.concurrent.Futures.allAsList; +import static com.google.common.util.concurrent.Futures.getUnchecked; + +public abstract class BaseListCookbookVersionsImpl { + + protected final ChefApi api; + + protected Logger logger = Logger.NULL; + + BaseListCookbookVersionsImpl(ChefApi api) { + this.api = checkNotNull(api, "api"); + } + + protected Iterable<? extends CookbookVersion> execute(Iterable<String> toGet) { + return concat(transform(toGet, new Function<String, Iterable<? extends CookbookVersion>>() { + + @Override + public Iterable<? extends CookbookVersion> apply(final String cookbook) { + // TODO getting each version could also go parallel + Set<String> cookbookVersions = api.listVersionsOfCookbook(cookbook); + Iterable<? extends CookbookVersion> cookbooksVersions = transform(cookbookVersions, + new Function<String, CookbookVersion>() { + @Override + public CookbookVersion apply(final String version) { + return api.getCookbook(cookbook, version); + } + } + ); + + logger.trace(String.format("getting versions of cookbook: %s", cookbook)); + return cookbooksVersions; + } + })); + + } + + protected Iterable<? extends CookbookVersion> executeConcurrently(final ListeningExecutorService executor, + Iterable<String> cookbookNames) { + return concat(transform(cookbookNames, new Function<String, Iterable<? extends CookbookVersion>>() { + + @Override + public Iterable<? extends CookbookVersion> apply(final String cookbook) { + // TODO getting each version could also go parallel + Set<String> cookbookVersions = api.listVersionsOfCookbook(cookbook); + ListenableFuture<List<CookbookVersion>> futures = allAsList(transform(cookbookVersions, + new Function<String, ListenableFuture<CookbookVersion>>() { + @Override + public ListenableFuture<CookbookVersion> apply(final String version) { + return executor.submit(new Callable<CookbookVersion>() { + @Override + public CookbookVersion call() throws Exception { + return api.getCookbook(cookbook, version); + } + }); + } + } + )); + + logger.trace(String.format("getting versions of cookbook: %s", cookbook)); + return getUnchecked(futures); + } + })); + } + +}
