From a14be57d2df76825e5b2df6c642cb5cfff3d51f7 Mon Sep 17 00:00:00 2001 From: cmp Date: Mon, 28 Nov 2016 16:20:18 -0600 Subject: [PATCH 01/14] Create gh-pages branch via GitHub --- index.html | 313 +++++++++++++++++++++++++++++++++ javascripts/scale.fix.js | 17 ++ params.json | 6 + stylesheets/github-light.css | 124 ++++++++++++++ stylesheets/styles.css | 324 +++++++++++++++++++++++++++++++++++ 5 files changed, 784 insertions(+) create mode 100644 index.html create mode 100644 javascripts/scale.fix.js create mode 100644 params.json create mode 100644 stylesheets/github-light.css create mode 100644 stylesheets/styles.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..e4df79b --- /dev/null +++ b/index.html @@ -0,0 +1,313 @@ + + + + + + Softlayer-java by softlayer + + + + + + + +
+
+

Softlayer-java

+

SoftLayer API Client for Java

+ +

View the Project on GitHub softlayer/softlayer-java

+ + + +
+
+

+SoftLayer API Client for Java

+ +

Build Status

+ +

+Introduction

+ +

This library provides a JVM client for the SoftLayer API. It +has code generated and compiled via Maven. The client can work with any Java 6+ runtime. It uses the code generation +project in gen/ to generate the service and type related code. Although likely to work in resource-constrained +environments (i.e. Android, J2ME, etc), using this is not recommended; Use the +REST API instead.

+ +

By default the HTTP client is the Java HttpUrlConnection and the JSON marshalling is done by +Gson. Both of these pieces can be exchanged for alternative implementations +(see below).

+ +

The examples/ project has sample uses of the API. It can be executed from Maven while inside the examples/ folder +via a command:

+ +
mvn -q compile exec:java -Dexec.args="EXAMPLE_NAME API_USER API_KEY"
+
+ +

Where EXAMPLE_NAME is the unqualified class name of an example in the com.softlayer.api.example package (e.g. +ListServers), API_USER is your API username, and API_KEY is your API key. NOTE: Some examples order virtual +servers and may charge your account.

+ +

+Using

+ +

To add the project you your Maven project, add the dependency:

+ +
<dependency>
+  <groupId>com.softlayer.api</groupId>
+  <artifactId>softlayer-api-client</artifactId>
+  <version>0.2.3</version>
+</dependency>
+ +

Note, the client published to Maven is built upon version change of this project. It will contain the generated +artifacts as of that time only. See "Building" for more information on how to regenerate the artifacts to get regular +additions to the SoftLayer API.

+ +

+Creating a Client

+ +

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply +instantiate it and provide your credentials:

+ +
import com.softlayer.api.*;
+
+ApiClient client = new RestApiClient().withCredentials("my user", "my api key");
+ +

If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the +RestApiClient. By default it is set to https://api.softlayer.com/rest/v3.1/.

+ +

+Making API Calls

+ +

Once a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer +account. A simple one is the Account service. Here's a call to get all of the hardware on the account:

+ +
import com.softlayer.api.service.Account;
+import com.softlayer.api.service.Hardware;
+
+for (Hardware hardware : Account.service(client).getHardware()) {
+    System.out.println("Hardware: " + hardware.getFullyQualifiedDomainName());
+}
+ +

Some calls on a service require an ID to know what object to act on. This can be obtained by passing in the numeric ID +into the service method or by calling asService on an object that has an ID. Here's an example of soft-rebooting a +virtual server with "reboot-test" as the hostname:

+ +
import com.softlayer.api.service.virtual.Guest;
+
+for (Guest guest : Account.service(client).getVirtualGuests()) {
+    if ("reboot-test".equals(guest.getHostname())) {
+        guest.asService(client).rebootSoft();
+    }
+}
+ +

Some calls require sending in data. This is done by just instantiating the object and populating the data. Here's an +example of ordering a new virtual server: (Note running this can charge your account)

+ +
import com.softlayer.api.service.virtual.Guest;
+
+Guest guest = new Guest();
+guest.setHostname("myhostname");
+guest.setDomain("example.com");
+guest.setStartCpus(1);
+guest.setMaxMemory(1024);
+guest.setHourlyBillingFlag(true);
+guest.setOperatingSystemReferenceCode("UBUNTU_LATEST");
+guest.setLocalDiskFlag(false);
+guest.setDatacenter(new Location());
+guest.getDatacenter().setName("dal05");
+guest = Guest.service(client).createObject(guest);
+System.out.println("Virtual server ordered with ID: " + guest.getId());
+ +

+Using Object Masks

+ +

Object masks are a great way to reduce the number of API calls to traverse the data graph of an object. For example, +here's how by just asking for an account, you can retrieve all your VLANs, their datacenter, and the firewall rules that +are on them:

+ +
import com.softlayer.api.service.Account;
+import com.softlayer.api.service.network.Vlan;
+import com.softlayer.api.service.network.vlan.firewall.Rule;
+
+Account.Service service = Account.service(client);
+service.withMask().networkVlans().vlanNumber();
+service.withMask().networkVlans().primaryRouter().datacenter().longName();
+service.withMask().networkVlans().firewallRules().
+    orderValue().
+    sourceIpAddress().
+    sourceIpCidr();
+
+for (Vlan vlan : service.getObject().getNetworkVlans()) {
+    for (Rule rule : vlan.getFirewallRules()) {
+        System.out.format("Rule %d on VLAN %d in %s has some restriction on subnet %s/%d\n",
+            rule.getOrderValue(), vlan.getVlanNumber(),
+            vlan.getPrimaryRouter().getDatacenter().getLongName(),
+            rule.getSourceIpAddress(), rule.getSourceIpCidr());
+    }
+}
+ +

All values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask +it is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer's +string-based object mask format. A string or an instance of a mask +can be given directly by calling setMask on the service. Note, when object masks are added on a service object, they +will be sent with every service call unless removed via clearMask or overwritten via withNewMask or setMask.

+ +

+Asynchronous Invocation

+ +

All services also provide an asynchronous interface. This can be obtained from a service by calling asAsync. Here's an +example of getting all top level billing items and listing when they were created:

+ +
import java.util.List;
+import com.softlayer.api.service.ResponseHandler;
+import com.softlayer.api.service.Account;
+import com.softlayer.api.service.billing.Item;
+
+Account.service(client).asAsync().getAllTopLevelBillingItems(new ResponseHandler<List<Item>>() {
+    @Override
+    public void onError(Exception ex) {
+        ex.printStackTrace();
+    }
+
+    @Override
+    public void onSuccess(List<Item> items) {
+        for (Item item : items) {
+            System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate());
+        }
+    }
+}).get();
+ +

Using the default HTTP client, this runs the call in a separate thread and calls the handler parameter upon completion. +The get at the end basically makes it wait forever so the application doesn't exit out from under us. With the default +HTTP client the asynchronous invocations are handled by a simple thread pool that defaults to a cached thread pool that +creates daemon threads. It can be changed:

+ +
import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import com.softlayer.api.service.RestApiClient;
+import com.softlayer.api.service.http.ThreadPoolHttpClientFactory;
+import com.softlayer.api.service.billing.Item;
+
+RestApiClient client = new RestApiClient();
+ExecutorService threadPool = Executors.newFixedThreadPool(3);
+((ThreadPoolHttpClientFactory) client.getHttpClientFactory()).setThreadPool(threadPool);
+ +

Unlike using the default thread pool, you will be responsible for shutting down this overridden thread pool as +necessary. Other HTTP client implementations may handle asynchrony differently and not use thread pools at all.

+ +

In addition to the callback-style above, can also get the response as a Future. Here's an example of waiting 10 +seconds to get all top level billing items:

+ +
import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.Future;
+import com.softlayer.api.service.Account;
+import com.softlayer.api.service.billing.Item;
+
+Future<List<Item>> response = Account.service(client).asAsync().getAllTopLevelBillingItems();
+List<Item> items = response.get(10, TimeUnit.SECONDS);
+for (Item item : items) {
+    System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate());
+}
+ +

+Thread Safety

+ +

No class in this library is guaranteed to be thread-safe. Callers are expected to keep this in mind when developing +with the library and to never use the same ApiClient (or any other object created with it) concurrently across +threads.

+ +

+Pagination

+ +

Sometimes there is a need to get the responses from the SoftLayer API in a paginated way instead of all at once. This +can be done by utilizing result limits. A result limit can be passed in with the number of results requested and the +offset to start reading from. Requesting smaller amounts of data will increase the performance of the call. Here is an +example of obtaining the first 10 tickets and outputting the total:

+ +
import com.softlayer.api.ResultLimit;
+import com.softlayer.api.service.Account;
+import com.softlayer.api.service.Ticket;
+
+Account.Service service = Account.service(client);
+service.setResultLimit(new ResultLimit(10));
+for (Ticket ticket : service.getTickets()) {
+    System.out.println("Got ticket " + ticket.getTitle());
+}
+System.out.println("Total tickets on the account: " + service.getLastResponseTotalItemCount());
+ +

The services are not guaranteed to be thread-safe on their own, so it is difficult to obtain the total with +getLastResponseTotalItemCount when using the service asynchronously. To assist with this when using the callback +style, the ResponseHandlerWithHeaders can be used instead of ResponseHandler. But the safest way is to only use a +single service per thread.

+ +

+Differences from the API

+ +

Due to restrictions on identifiers in Java, some properties, methods, classes, and packages will be named differently +from the naming used by the API. For example, an API property that starts with a number will be prepended with 'z'. +Java keywords that appear in identifiers may +also be replaced.

+ +

+Building

+ +

This project is intentionally provided without all of the service code. Normal Maven install and package commands +work properly and will regenerate the client. To specifically regenerate the Java service-related files, run:

+ +
mvn generate-sources
+
+ +

+Customization

+ +

+Logging

+ +

Logging the requests and response to stdout can be enabled by invoking withLoggingEnabled on the RestApiClient. In +order to log elsewhere, simply make your own implementation of RestApiClient with logRequest and logResponse +overridden.

+ +

+HTTP Client

+ +

The default HTTP client that is used is the JVM's native HttpUrlConnection. In order to create your own, alternative +implementation you must implement com.softlayer.api.http.HttpClientFactory. Once implemented, this can be explicitly +set on the RestApiClient by calling setHttpClientFactory. Instead of setting the factory manually, you can also +leverage Java's ServiceLoader mechanism to have it used by default. This involves adding the fully qualified class +name of your implementation on a single line in a file in the JAR at +META-INF/com.softlayer.api.http.HttpClientFactory.

+ +

+JSON Marshalling

+ +

The default JSON marshaller that is used is Gson. In order to create your own, +alternative implementation you must implement com.softlayer.api.json.JsonMarshallerFactyory. Once implemented, this +can be explicitly set on the RestApiClient by calling setJsonMarshallerFactory. Instead of setting the factory +manually, you can also leverage Java's ServiceLoader mechanism to have it used by default. This involves adding the +fully qualified class name of your implementation on a single line in a file in the JAR at +META-INF/com.softlayer.api.json.JsonMarshallerFactory.

+ +

+Copyright

+ +

This software is Copyright (c) 2016 The SoftLayer Developer Network. See the bundled LICENSE file for more information.

+
+ +
+ + + + diff --git a/javascripts/scale.fix.js b/javascripts/scale.fix.js new file mode 100644 index 0000000..87a40ca --- /dev/null +++ b/javascripts/scale.fix.js @@ -0,0 +1,17 @@ +var metas = document.getElementsByTagName('meta'); +var i; +if (navigator.userAgent.match(/iPhone/i)) { + for (i=0; i\r\n com.softlayer.api\r\n softlayer-api-client\r\n 0.2.3\r\n\r\n```\r\n\r\nNote, the client published to Maven is built upon version change of this project. It will contain the generated\r\nartifacts as of that time only. See \"Building\" for more information on how to regenerate the artifacts to get regular\r\nadditions to the SoftLayer API.\r\n\r\n### Creating a Client\r\n\r\nAll clients are instances of `ApiClient`. Currently there is only one implementation, the `RestApiClient`. Simply\r\ninstantiate it and provide your credentials:\r\n\r\n```java\r\nimport com.softlayer.api.*;\r\n\r\nApiClient client = new RestApiClient().withCredentials(\"my user\", \"my api key\");\r\n```\r\n\r\nIf the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the\r\n`RestApiClient`. By default it is set to `https://api.softlayer.com/rest/v3.1/`.\r\n\r\n### Making API Calls\r\n\r\nOnce a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer\r\naccount. A simple one is the `Account` service. Here's a call to get all of the hardware on the account:\r\n\r\n```java\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.Hardware;\r\n\r\nfor (Hardware hardware : Account.service(client).getHardware()) {\r\n System.out.println(\"Hardware: \" + hardware.getFullyQualifiedDomainName());\r\n}\r\n```\r\n\r\nSome calls on a service require an ID to know what object to act on. This can be obtained by passing in the numeric ID\r\ninto the `service` method or by calling `asService` on an object that has an ID. Here's an example of soft-rebooting a\r\nvirtual server with \"reboot-test\" as the hostname:\r\n\r\n```java\r\nimport com.softlayer.api.service.virtual.Guest;\r\n\r\nfor (Guest guest : Account.service(client).getVirtualGuests()) {\r\n if (\"reboot-test\".equals(guest.getHostname())) {\r\n guest.asService(client).rebootSoft();\r\n }\r\n}\r\n```\r\n\r\nSome calls require sending in data. This is done by just instantiating the object and populating the data. Here's an\r\nexample of ordering a new virtual server: (Note running this can charge your account)\r\n\r\n```java\r\nimport com.softlayer.api.service.virtual.Guest;\r\n\r\nGuest guest = new Guest();\r\nguest.setHostname(\"myhostname\");\r\nguest.setDomain(\"example.com\");\r\nguest.setStartCpus(1);\r\nguest.setMaxMemory(1024);\r\nguest.setHourlyBillingFlag(true);\r\nguest.setOperatingSystemReferenceCode(\"UBUNTU_LATEST\");\r\nguest.setLocalDiskFlag(false);\r\nguest.setDatacenter(new Location());\r\nguest.getDatacenter().setName(\"dal05\");\r\nguest = Guest.service(client).createObject(guest);\r\nSystem.out.println(\"Virtual server ordered with ID: \" + guest.getId());\r\n```\r\n\r\n### Using Object Masks\r\n\r\nObject masks are a great way to reduce the number of API calls to traverse the data graph of an object. For example,\r\nhere's how by just asking for an account, you can retrieve all your VLANs, their datacenter, and the firewall rules that\r\nare on them:\r\n\r\n```java\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.network.Vlan;\r\nimport com.softlayer.api.service.network.vlan.firewall.Rule;\r\n\r\nAccount.Service service = Account.service(client);\r\nservice.withMask().networkVlans().vlanNumber();\r\nservice.withMask().networkVlans().primaryRouter().datacenter().longName();\r\nservice.withMask().networkVlans().firewallRules().\r\n orderValue().\r\n sourceIpAddress().\r\n sourceIpCidr();\r\n\r\nfor (Vlan vlan : service.getObject().getNetworkVlans()) {\r\n for (Rule rule : vlan.getFirewallRules()) {\r\n System.out.format(\"Rule %d on VLAN %d in %s has some restriction on subnet %s/%d\\n\",\r\n rule.getOrderValue(), vlan.getVlanNumber(),\r\n vlan.getPrimaryRouter().getDatacenter().getLongName(),\r\n rule.getSourceIpAddress(), rule.getSourceIpCidr());\r\n }\r\n}\r\n```\r\n\r\nAll values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask\r\nit is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer's\r\n[string-based object mask format](http://sldn.softlayer.com/article/Object-Masks). A string or an instance of a mask\r\ncan be given directly by calling `setMask` on the service. Note, when object masks are added on a service object, they\r\nwill be sent with every service call unless removed via `clearMask` or overwritten via `withNewMask` or `setMask`.\r\n\r\n### Asynchronous Invocation\r\n\r\nAll services also provide an asynchronous interface. This can be obtained from a service by calling `asAsync`. Here's an\r\nexample of getting all top level billing items and listing when they were created:\r\n\r\n```java\r\nimport java.util.List;\r\nimport com.softlayer.api.service.ResponseHandler;\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.billing.Item;\r\n\r\nAccount.service(client).asAsync().getAllTopLevelBillingItems(new ResponseHandler>() {\r\n @Override\r\n public void onError(Exception ex) {\r\n ex.printStackTrace();\r\n }\r\n\r\n @Override\r\n public void onSuccess(List items) {\r\n for (Item item : items) {\r\n System.out.format(\"Billing item %s created on %s\\n\", item.getDescription(), item.getCreateDate());\r\n }\r\n }\r\n}).get();\r\n```\r\n\r\nUsing the default HTTP client, this runs the call in a separate thread and calls the handler parameter upon completion.\r\nThe `get` at the end basically makes it wait forever so the application doesn't exit out from under us. With the default\r\nHTTP client the asynchronous invocations are handled by a simple thread pool that defaults to a cached thread pool that\r\ncreates daemon threads. It can be changed:\r\n\r\n```java\r\nimport java.util.concurrent.Executors;\r\nimport java.util.concurrent.ExecutorService;\r\nimport com.softlayer.api.service.RestApiClient;\r\nimport com.softlayer.api.service.http.ThreadPoolHttpClientFactory;\r\nimport com.softlayer.api.service.billing.Item;\r\n\r\nRestApiClient client = new RestApiClient();\r\nExecutorService threadPool = Executors.newFixedThreadPool(3);\r\n((ThreadPoolHttpClientFactory) client.getHttpClientFactory()).setThreadPool(threadPool);\r\n```\r\n\r\nUnlike using the default thread pool, you will be responsible for shutting down this overridden thread pool as\r\nnecessary. Other HTTP client implementations may handle asynchrony differently and not use thread pools at all.\r\n\r\nIn addition to the callback-style above, can also get the response as a `Future`. Here's an example of waiting 10\r\nseconds to get all top level billing items:\r\n\r\n```java\r\nimport java.util.List;\r\nimport java.util.concurrent.TimeUnit;\r\nimport java.util.concurrent.Future;\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.billing.Item;\r\n\r\nFuture> response = Account.service(client).asAsync().getAllTopLevelBillingItems();\r\nList items = response.get(10, TimeUnit.SECONDS);\r\nfor (Item item : items) {\r\n System.out.format(\"Billing item %s created on %s\\n\", item.getDescription(), item.getCreateDate());\r\n}\r\n```\r\n\r\n### Thread Safety\r\n\r\nNo class in this library is guaranteed to be thread-safe. Callers are expected to keep this in mind when developing\r\nwith the library and to never use the same `ApiClient` (or any other object created with it) concurrently across\r\nthreads.\r\n\r\n### Pagination\r\n\r\nSometimes there is a need to get the responses from the SoftLayer API in a paginated way instead of all at once. This\r\ncan be done by utilizing result limits. A result limit can be passed in with the number of results requested and the\r\noffset to start reading from. Requesting smaller amounts of data will increase the performance of the call. Here is an\r\nexample of obtaining the first 10 tickets and outputting the total:\r\n\r\n```java\r\nimport com.softlayer.api.ResultLimit;\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.Ticket;\r\n\r\nAccount.Service service = Account.service(client);\r\nservice.setResultLimit(new ResultLimit(10));\r\nfor (Ticket ticket : service.getTickets()) {\r\n System.out.println(\"Got ticket \" + ticket.getTitle());\r\n}\r\nSystem.out.println(\"Total tickets on the account: \" + service.getLastResponseTotalItemCount());\r\n```\r\n\r\nThe services are not guaranteed to be thread-safe on their own, so it is difficult to obtain the total with\r\n`getLastResponseTotalItemCount` when using the service asynchronously. To assist with this when using the callback\r\nstyle, the `ResponseHandlerWithHeaders` can be used instead of `ResponseHandler`. But the safest way is to only use a\r\nsingle service per thread.\r\n\r\n### Differences from the API\r\n\r\nDue to restrictions on identifiers in Java, some properties, methods, classes, and packages will be named differently\r\nfrom the naming used by the API. For example, an API property that starts with a number will be prepended with 'z'.\r\n[Java keywords](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.9) that appear in identifiers may\r\nalso be replaced.\r\n\r\n## Building\r\n\r\nThis project is intentionally provided without all of the service code. Normal Maven `install` and `package` commands\r\nwork properly and will regenerate the client. To specifically regenerate the Java service-related files, run:\r\n\r\n mvn generate-sources\r\n\r\n## Customization\r\n\r\n### Logging\r\n\r\nLogging the requests and response to stdout can be enabled by invoking `withLoggingEnabled` on the `RestApiClient`. In\r\norder to log elsewhere, simply make your own implementation of `RestApiClient` with `logRequest` and `logResponse`\r\noverridden.\r\n\r\n### HTTP Client\r\n\r\nThe default HTTP client that is used is the JVM's native `HttpUrlConnection`. In order to create your own, alternative\r\nimplementation you must implement `com.softlayer.api.http.HttpClientFactory`. Once implemented, this can be explicitly\r\nset on the `RestApiClient` by calling `setHttpClientFactory`. Instead of setting the factory manually, you can also\r\nleverage Java's `ServiceLoader` mechanism to have it used by default. This involves adding the fully qualified class\r\nname of your implementation on a single line in a file in the JAR at\r\n`META-INF/com.softlayer.api.http.HttpClientFactory`.\r\n\r\n### JSON Marshalling\r\n\r\nThe default JSON marshaller that is used is [Gson](https://code.google.com/p/google-gson/). In order to create your own,\r\nalternative implementation you must implement `com.softlayer.api.json.JsonMarshallerFactyory`. Once implemented, this\r\ncan be explicitly set on the `RestApiClient` by calling `setJsonMarshallerFactory`. Instead of setting the factory\r\nmanually, you can also leverage Java's `ServiceLoader` mechanism to have it used by default. This involves adding the\r\nfully qualified class name of your implementation on a single line in a file in the JAR at\r\n`META-INF/com.softlayer.api.json.JsonMarshallerFactory`.\r\n\r\n## Copyright\r\n\r\nThis software is Copyright (c) 2016 The SoftLayer Developer Network. See the bundled LICENSE file for more information.\r\n", + "note": "Don't delete this file! It's used internally to help with page regeneration." +} \ No newline at end of file diff --git a/stylesheets/github-light.css b/stylesheets/github-light.css new file mode 100644 index 0000000..0c6b24d --- /dev/null +++ b/stylesheets/github-light.css @@ -0,0 +1,124 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 GitHub, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +.pl-c /* comment */ { + color: #969896; +} + +.pl-c1 /* constant, variable.other.constant, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header */, +.pl-s .pl-v /* string variable */ { + color: #0086b3; +} + +.pl-e /* entity */, +.pl-en /* entity.name */ { + color: #795da3; +} + +.pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */, +.pl-s .pl-s1 /* string source */ { + color: #333; +} + +.pl-ent /* entity.name.tag */ { + color: #63a35c; +} + +.pl-k /* keyword, storage, storage.type */ { + color: #a71d5d; +} + +.pl-s /* string */, +.pl-pds /* punctuation.definition.string, string.regexp.character-class */, +.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */, +.pl-sr /* string.regexp */, +.pl-sr .pl-cce /* string.regexp constant.character.escape */, +.pl-sr .pl-sre /* string.regexp source.ruby.embedded */, +.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ { + color: #183691; +} + +.pl-v /* variable */ { + color: #ed6a43; +} + +.pl-id /* invalid.deprecated */ { + color: #b52a1d; +} + +.pl-ii /* invalid.illegal */ { + color: #f8f8f8; + background-color: #b52a1d; +} + +.pl-sr .pl-cce /* string.regexp constant.character.escape */ { + font-weight: bold; + color: #63a35c; +} + +.pl-ml /* markup.list */ { + color: #693a17; +} + +.pl-mh /* markup.heading */, +.pl-mh .pl-en /* markup.heading entity.name */, +.pl-ms /* meta.separator */ { + font-weight: bold; + color: #1d3e81; +} + +.pl-mq /* markup.quote */ { + color: #008080; +} + +.pl-mi /* markup.italic */ { + font-style: italic; + color: #333; +} + +.pl-mb /* markup.bold */ { + font-weight: bold; + color: #333; +} + +.pl-md /* markup.deleted, meta.diff.header.from-file */ { + color: #bd2c00; + background-color: #ffecec; +} + +.pl-mi1 /* markup.inserted, meta.diff.header.to-file */ { + color: #55a532; + background-color: #eaffea; +} + +.pl-mdr /* meta.diff.range */ { + font-weight: bold; + color: #795da3; +} + +.pl-mo /* meta.output */ { + color: #1d3e81; +} + diff --git a/stylesheets/styles.css b/stylesheets/styles.css new file mode 100644 index 0000000..2e1768e --- /dev/null +++ b/stylesheets/styles.css @@ -0,0 +1,324 @@ +@font-face { + font-family: 'Noto Sans'; + font-weight: 400; + font-style: normal; + src: url('../fonts/Noto-Sans-regular/Noto-Sans-regular.eot'); + src: url('../fonts/Noto-Sans-regular/Noto-Sans-regular.eot?#iefix') format('embedded-opentype'), + local('Noto Sans'), + local('Noto-Sans-regular'), + url('../fonts/Noto-Sans-regular/Noto-Sans-regular.woff2') format('woff2'), + url('../fonts/Noto-Sans-regular/Noto-Sans-regular.woff') format('woff'), + url('../fonts/Noto-Sans-regular/Noto-Sans-regular.ttf') format('truetype'), + url('../fonts/Noto-Sans-regular/Noto-Sans-regular.svg#NotoSans') format('svg'); +} + +@font-face { + font-family: 'Noto Sans'; + font-weight: 700; + font-style: normal; + src: url('../fonts/Noto-Sans-700/Noto-Sans-700.eot'); + src: url('../fonts/Noto-Sans-700/Noto-Sans-700.eot?#iefix') format('embedded-opentype'), + local('Noto Sans Bold'), + local('Noto-Sans-700'), + url('../fonts/Noto-Sans-700/Noto-Sans-700.woff2') format('woff2'), + url('../fonts/Noto-Sans-700/Noto-Sans-700.woff') format('woff'), + url('../fonts/Noto-Sans-700/Noto-Sans-700.ttf') format('truetype'), + url('../fonts/Noto-Sans-700/Noto-Sans-700.svg#NotoSans') format('svg'); +} + +@font-face { + font-family: 'Noto Sans'; + font-weight: 400; + font-style: italic; + src: url('../fonts/Noto-Sans-italic/Noto-Sans-italic.eot'); + src: url('../fonts/Noto-Sans-italic/Noto-Sans-italic.eot?#iefix') format('embedded-opentype'), + local('Noto Sans Italic'), + local('Noto-Sans-italic'), + url('../fonts/Noto-Sans-italic/Noto-Sans-italic.woff2') format('woff2'), + url('../fonts/Noto-Sans-italic/Noto-Sans-italic.woff') format('woff'), + url('../fonts/Noto-Sans-italic/Noto-Sans-italic.ttf') format('truetype'), + url('../fonts/Noto-Sans-italic/Noto-Sans-italic.svg#NotoSans') format('svg'); +} + +@font-face { + font-family: 'Noto Sans'; + font-weight: 700; + font-style: italic; + src: url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot'); + src: url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot?#iefix') format('embedded-opentype'), + local('Noto Sans Bold Italic'), + local('Noto-Sans-700italic'), + url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff2') format('woff2'), + url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff') format('woff'), + url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.ttf') format('truetype'), + url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.svg#NotoSans') format('svg'); +} + +body { + background-color: #fff; + padding:50px; + font: 14px/1.5 "Noto Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + color:#727272; + font-weight:400; +} + +h1, h2, h3, h4, h5, h6 { + color:#222; + margin:0 0 20px; +} + +p, ul, ol, table, pre, dl { + margin:0 0 20px; +} + +h1, h2, h3 { + line-height:1.1; +} + +h1 { + font-size:28px; +} + +h2 { + color:#393939; +} + +h3, h4, h5, h6 { + color:#494949; +} + +a { + color:#39c; + text-decoration:none; +} + +a:hover { + color:#069; +} + +a small { + font-size:11px; + color:#777; + margin-top:-0.3em; + display:block; +} + +a:hover small { + color:#777; +} + +.wrapper { + width:860px; + margin:0 auto; +} + +blockquote { + border-left:1px solid #e5e5e5; + margin:0; + padding:0 0 0 20px; + font-style:italic; +} + +code, pre { + font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal, Consolas, Liberation Mono, DejaVu Sans Mono, Courier New, monospace; + color:#333; + font-size:12px; +} + +pre { + padding:8px 15px; + background: #f8f8f8; + border-radius:5px; + border:1px solid #e5e5e5; + overflow-x: auto; +} + +table { + width:100%; + border-collapse:collapse; +} + +th, td { + text-align:left; + padding:5px 10px; + border-bottom:1px solid #e5e5e5; +} + +dt { + color:#444; + font-weight:700; +} + +th { + color:#444; +} + +img { + max-width:100%; +} + +header { + width:270px; + float:left; + position:fixed; + -webkit-font-smoothing:subpixel-antialiased; +} + +header ul { + list-style:none; + height:40px; + padding:0; + background: #f4f4f4; + border-radius:5px; + border:1px solid #e0e0e0; + width:270px; +} + +header li { + width:89px; + float:left; + border-right:1px solid #e0e0e0; + height:40px; +} + +header li:first-child a { + border-radius:5px 0 0 5px; +} + +header li:last-child a { + border-radius:0 5px 5px 0; +} + +header ul a { + line-height:1; + font-size:11px; + color:#999; + display:block; + text-align:center; + padding-top:6px; + height:34px; +} + +header ul a:hover { + color:#999; +} + +header ul a:active { + background-color:#f0f0f0; +} + +strong { + color:#222; + font-weight:700; +} + +header ul li + li + li { + border-right:none; + width:89px; +} + +header ul a strong { + font-size:14px; + display:block; + color:#222; +} + +section { + width:500px; + float:right; + padding-bottom:50px; +} + +small { + font-size:11px; +} + +hr { + border:0; + background:#e5e5e5; + height:1px; + margin:0 0 20px; +} + +footer { + width:270px; + float:left; + position:fixed; + bottom:50px; + -webkit-font-smoothing:subpixel-antialiased; +} + +@media print, screen and (max-width: 960px) { + + div.wrapper { + width:auto; + margin:0; + } + + header, section, footer { + float:none; + position:static; + width:auto; + } + + header { + padding-right:320px; + } + + section { + border:1px solid #e5e5e5; + border-width:1px 0; + padding:20px 0; + margin:0 0 20px; + } + + header a small { + display:inline; + } + + header ul { + position:absolute; + right:50px; + top:52px; + } +} + +@media print, screen and (max-width: 720px) { + body { + word-wrap:break-word; + } + + header { + padding:0; + } + + header ul, header p.view { + position:static; + } + + pre, code { + word-wrap:normal; + } +} + +@media print, screen and (max-width: 480px) { + body { + padding:15px; + } + + header ul { + width:99%; + } + + header li, header ul li + li + li { + width:33%; + } +} + +@media print { + body { + padding:0.4in; + font-size:12pt; + color:#444; + } +} From 27cd30c195bdfdf703976dfcd97cbb81bea64608 Mon Sep 17 00:00:00 2001 From: cmp Date: Mon, 30 Dec 2019 11:44:36 -0600 Subject: [PATCH 02/14] Set theme jekyll-theme-minimal and migrate Page Generator content --- _config.yml | 8 + index.html | 313 --------------------------------- index.md | 275 +++++++++++++++++++++++++++++ javascripts/scale.fix.js | 17 -- params.json | 6 - stylesheets/github-light.css | 124 -------------- stylesheets/styles.css | 324 ----------------------------------- 7 files changed, 283 insertions(+), 784 deletions(-) create mode 100644 _config.yml delete mode 100644 index.html create mode 100644 index.md delete mode 100644 javascripts/scale.fix.js delete mode 100644 params.json delete mode 100644 stylesheets/github-light.css delete mode 100644 stylesheets/styles.css diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..f9dd549 --- /dev/null +++ b/_config.yml @@ -0,0 +1,8 @@ +title: Softlayer-java +description: SoftLayer API Client for Java +google_analytics: +show_downloads: true +theme: jekyll-theme-minimal + +gems: + - jekyll-mentions diff --git a/index.html b/index.html deleted file mode 100644 index e4df79b..0000000 --- a/index.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - Softlayer-java by softlayer - - - - - - - -
-
-

Softlayer-java

-

SoftLayer API Client for Java

- -

View the Project on GitHub softlayer/softlayer-java

- - - -
-
-

-SoftLayer API Client for Java

- -

Build Status

- -

-Introduction

- -

This library provides a JVM client for the SoftLayer API. It -has code generated and compiled via Maven. The client can work with any Java 6+ runtime. It uses the code generation -project in gen/ to generate the service and type related code. Although likely to work in resource-constrained -environments (i.e. Android, J2ME, etc), using this is not recommended; Use the -REST API instead.

- -

By default the HTTP client is the Java HttpUrlConnection and the JSON marshalling is done by -Gson. Both of these pieces can be exchanged for alternative implementations -(see below).

- -

The examples/ project has sample uses of the API. It can be executed from Maven while inside the examples/ folder -via a command:

- -
mvn -q compile exec:java -Dexec.args="EXAMPLE_NAME API_USER API_KEY"
-
- -

Where EXAMPLE_NAME is the unqualified class name of an example in the com.softlayer.api.example package (e.g. -ListServers), API_USER is your API username, and API_KEY is your API key. NOTE: Some examples order virtual -servers and may charge your account.

- -

-Using

- -

To add the project you your Maven project, add the dependency:

- -
<dependency>
-  <groupId>com.softlayer.api</groupId>
-  <artifactId>softlayer-api-client</artifactId>
-  <version>0.2.3</version>
-</dependency>
- -

Note, the client published to Maven is built upon version change of this project. It will contain the generated -artifacts as of that time only. See "Building" for more information on how to regenerate the artifacts to get regular -additions to the SoftLayer API.

- -

-Creating a Client

- -

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply -instantiate it and provide your credentials:

- -
import com.softlayer.api.*;
-
-ApiClient client = new RestApiClient().withCredentials("my user", "my api key");
- -

If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the -RestApiClient. By default it is set to https://api.softlayer.com/rest/v3.1/.

- -

-Making API Calls

- -

Once a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer -account. A simple one is the Account service. Here's a call to get all of the hardware on the account:

- -
import com.softlayer.api.service.Account;
-import com.softlayer.api.service.Hardware;
-
-for (Hardware hardware : Account.service(client).getHardware()) {
-    System.out.println("Hardware: " + hardware.getFullyQualifiedDomainName());
-}
- -

Some calls on a service require an ID to know what object to act on. This can be obtained by passing in the numeric ID -into the service method or by calling asService on an object that has an ID. Here's an example of soft-rebooting a -virtual server with "reboot-test" as the hostname:

- -
import com.softlayer.api.service.virtual.Guest;
-
-for (Guest guest : Account.service(client).getVirtualGuests()) {
-    if ("reboot-test".equals(guest.getHostname())) {
-        guest.asService(client).rebootSoft();
-    }
-}
- -

Some calls require sending in data. This is done by just instantiating the object and populating the data. Here's an -example of ordering a new virtual server: (Note running this can charge your account)

- -
import com.softlayer.api.service.virtual.Guest;
-
-Guest guest = new Guest();
-guest.setHostname("myhostname");
-guest.setDomain("example.com");
-guest.setStartCpus(1);
-guest.setMaxMemory(1024);
-guest.setHourlyBillingFlag(true);
-guest.setOperatingSystemReferenceCode("UBUNTU_LATEST");
-guest.setLocalDiskFlag(false);
-guest.setDatacenter(new Location());
-guest.getDatacenter().setName("dal05");
-guest = Guest.service(client).createObject(guest);
-System.out.println("Virtual server ordered with ID: " + guest.getId());
- -

-Using Object Masks

- -

Object masks are a great way to reduce the number of API calls to traverse the data graph of an object. For example, -here's how by just asking for an account, you can retrieve all your VLANs, their datacenter, and the firewall rules that -are on them:

- -
import com.softlayer.api.service.Account;
-import com.softlayer.api.service.network.Vlan;
-import com.softlayer.api.service.network.vlan.firewall.Rule;
-
-Account.Service service = Account.service(client);
-service.withMask().networkVlans().vlanNumber();
-service.withMask().networkVlans().primaryRouter().datacenter().longName();
-service.withMask().networkVlans().firewallRules().
-    orderValue().
-    sourceIpAddress().
-    sourceIpCidr();
-
-for (Vlan vlan : service.getObject().getNetworkVlans()) {
-    for (Rule rule : vlan.getFirewallRules()) {
-        System.out.format("Rule %d on VLAN %d in %s has some restriction on subnet %s/%d\n",
-            rule.getOrderValue(), vlan.getVlanNumber(),
-            vlan.getPrimaryRouter().getDatacenter().getLongName(),
-            rule.getSourceIpAddress(), rule.getSourceIpCidr());
-    }
-}
- -

All values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask -it is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer's -string-based object mask format. A string or an instance of a mask -can be given directly by calling setMask on the service. Note, when object masks are added on a service object, they -will be sent with every service call unless removed via clearMask or overwritten via withNewMask or setMask.

- -

-Asynchronous Invocation

- -

All services also provide an asynchronous interface. This can be obtained from a service by calling asAsync. Here's an -example of getting all top level billing items and listing when they were created:

- -
import java.util.List;
-import com.softlayer.api.service.ResponseHandler;
-import com.softlayer.api.service.Account;
-import com.softlayer.api.service.billing.Item;
-
-Account.service(client).asAsync().getAllTopLevelBillingItems(new ResponseHandler<List<Item>>() {
-    @Override
-    public void onError(Exception ex) {
-        ex.printStackTrace();
-    }
-
-    @Override
-    public void onSuccess(List<Item> items) {
-        for (Item item : items) {
-            System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate());
-        }
-    }
-}).get();
- -

Using the default HTTP client, this runs the call in a separate thread and calls the handler parameter upon completion. -The get at the end basically makes it wait forever so the application doesn't exit out from under us. With the default -HTTP client the asynchronous invocations are handled by a simple thread pool that defaults to a cached thread pool that -creates daemon threads. It can be changed:

- -
import java.util.concurrent.Executors;
-import java.util.concurrent.ExecutorService;
-import com.softlayer.api.service.RestApiClient;
-import com.softlayer.api.service.http.ThreadPoolHttpClientFactory;
-import com.softlayer.api.service.billing.Item;
-
-RestApiClient client = new RestApiClient();
-ExecutorService threadPool = Executors.newFixedThreadPool(3);
-((ThreadPoolHttpClientFactory) client.getHttpClientFactory()).setThreadPool(threadPool);
- -

Unlike using the default thread pool, you will be responsible for shutting down this overridden thread pool as -necessary. Other HTTP client implementations may handle asynchrony differently and not use thread pools at all.

- -

In addition to the callback-style above, can also get the response as a Future. Here's an example of waiting 10 -seconds to get all top level billing items:

- -
import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.Future;
-import com.softlayer.api.service.Account;
-import com.softlayer.api.service.billing.Item;
-
-Future<List<Item>> response = Account.service(client).asAsync().getAllTopLevelBillingItems();
-List<Item> items = response.get(10, TimeUnit.SECONDS);
-for (Item item : items) {
-    System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate());
-}
- -

-Thread Safety

- -

No class in this library is guaranteed to be thread-safe. Callers are expected to keep this in mind when developing -with the library and to never use the same ApiClient (or any other object created with it) concurrently across -threads.

- -

-Pagination

- -

Sometimes there is a need to get the responses from the SoftLayer API in a paginated way instead of all at once. This -can be done by utilizing result limits. A result limit can be passed in with the number of results requested and the -offset to start reading from. Requesting smaller amounts of data will increase the performance of the call. Here is an -example of obtaining the first 10 tickets and outputting the total:

- -
import com.softlayer.api.ResultLimit;
-import com.softlayer.api.service.Account;
-import com.softlayer.api.service.Ticket;
-
-Account.Service service = Account.service(client);
-service.setResultLimit(new ResultLimit(10));
-for (Ticket ticket : service.getTickets()) {
-    System.out.println("Got ticket " + ticket.getTitle());
-}
-System.out.println("Total tickets on the account: " + service.getLastResponseTotalItemCount());
- -

The services are not guaranteed to be thread-safe on their own, so it is difficult to obtain the total with -getLastResponseTotalItemCount when using the service asynchronously. To assist with this when using the callback -style, the ResponseHandlerWithHeaders can be used instead of ResponseHandler. But the safest way is to only use a -single service per thread.

- -

-Differences from the API

- -

Due to restrictions on identifiers in Java, some properties, methods, classes, and packages will be named differently -from the naming used by the API. For example, an API property that starts with a number will be prepended with 'z'. -Java keywords that appear in identifiers may -also be replaced.

- -

-Building

- -

This project is intentionally provided without all of the service code. Normal Maven install and package commands -work properly and will regenerate the client. To specifically regenerate the Java service-related files, run:

- -
mvn generate-sources
-
- -

-Customization

- -

-Logging

- -

Logging the requests and response to stdout can be enabled by invoking withLoggingEnabled on the RestApiClient. In -order to log elsewhere, simply make your own implementation of RestApiClient with logRequest and logResponse -overridden.

- -

-HTTP Client

- -

The default HTTP client that is used is the JVM's native HttpUrlConnection. In order to create your own, alternative -implementation you must implement com.softlayer.api.http.HttpClientFactory. Once implemented, this can be explicitly -set on the RestApiClient by calling setHttpClientFactory. Instead of setting the factory manually, you can also -leverage Java's ServiceLoader mechanism to have it used by default. This involves adding the fully qualified class -name of your implementation on a single line in a file in the JAR at -META-INF/com.softlayer.api.http.HttpClientFactory.

- -

-JSON Marshalling

- -

The default JSON marshaller that is used is Gson. In order to create your own, -alternative implementation you must implement com.softlayer.api.json.JsonMarshallerFactyory. Once implemented, this -can be explicitly set on the RestApiClient by calling setJsonMarshallerFactory. Instead of setting the factory -manually, you can also leverage Java's ServiceLoader mechanism to have it used by default. This involves adding the -fully qualified class name of your implementation on a single line in a file in the JAR at -META-INF/com.softlayer.api.json.JsonMarshallerFactory.

- -

-Copyright

- -

This software is Copyright (c) 2016 The SoftLayer Developer Network. See the bundled LICENSE file for more information.

-
- -
- - - - diff --git a/index.md b/index.md new file mode 100644 index 0000000..3c0605f --- /dev/null +++ b/index.md @@ -0,0 +1,275 @@ +# SoftLayer API Client for Java + +[![Build Status](https://travis-ci.org/softlayer/softlayer-java.svg)](https://travis-ci.org/softlayer/softlayer-java) + +## Introduction + +This library provides a JVM client for the [SoftLayer API](http://sldn.softlayer.com/article/SoftLayer-API-Overview). It +has code generated and compiled via Maven. The client can work with any Java 6+ runtime. It uses the code generation +project in `gen/` to generate the service and type related code. Although likely to work in resource-constrained +environments (i.e. Android, J2ME, etc), using this is not recommended; Use the +[REST](http://sldn.softlayer.com/article/REST) API instead. + +By default the HTTP client is the Java `HttpUrlConnection` and the JSON marshalling is done by +[Gson](https://code.google.com/p/google-gson/). Both of these pieces can be exchanged for alternative implementations +(see below). + +The `examples/` project has sample uses of the API. It can be executed from Maven while inside the `examples/` folder +via a command: + + mvn -q compile exec:java -Dexec.args="EXAMPLE_NAME API_USER API_KEY" + +Where `EXAMPLE_NAME` is the unqualified class name of an example in the `com.softlayer.api.example` package (e.g. +`ListServers`), `API_USER` is your API username, and `API_KEY` is your API key. NOTE: Some examples order virtual +servers and may charge your account. + +## Using + +To add the project you your Maven project, add the dependency: + +```xml + + com.softlayer.api + softlayer-api-client + 0.2.3 + +``` + +Note, the client published to Maven is built upon version change of this project. It will contain the generated +artifacts as of that time only. See "Building" for more information on how to regenerate the artifacts to get regular +additions to the SoftLayer API. + +### Creating a Client + +All clients are instances of `ApiClient`. Currently there is only one implementation, the `RestApiClient`. Simply +instantiate it and provide your credentials: + +```java +import com.softlayer.api.*; + +ApiClient client = new RestApiClient().withCredentials("my user", "my api key"); +``` + +If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the +`RestApiClient`. By default it is set to `https://api.softlayer.com/rest/v3.1/`. + +### Making API Calls + +Once a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer +account. A simple one is the `Account` service. Here's a call to get all of the hardware on the account: + +```java +import com.softlayer.api.service.Account; +import com.softlayer.api.service.Hardware; + +for (Hardware hardware : Account.service(client).getHardware()) { + System.out.println("Hardware: " + hardware.getFullyQualifiedDomainName()); +} +``` + +Some calls on a service require an ID to know what object to act on. This can be obtained by passing in the numeric ID +into the `service` method or by calling `asService` on an object that has an ID. Here's an example of soft-rebooting a +virtual server with "reboot-test" as the hostname: + +```java +import com.softlayer.api.service.virtual.Guest; + +for (Guest guest : Account.service(client).getVirtualGuests()) { + if ("reboot-test".equals(guest.getHostname())) { + guest.asService(client).rebootSoft(); + } +} +``` + +Some calls require sending in data. This is done by just instantiating the object and populating the data. Here's an +example of ordering a new virtual server: (Note running this can charge your account) + +```java +import com.softlayer.api.service.virtual.Guest; + +Guest guest = new Guest(); +guest.setHostname("myhostname"); +guest.setDomain("example.com"); +guest.setStartCpus(1); +guest.setMaxMemory(1024); +guest.setHourlyBillingFlag(true); +guest.setOperatingSystemReferenceCode("UBUNTU_LATEST"); +guest.setLocalDiskFlag(false); +guest.setDatacenter(new Location()); +guest.getDatacenter().setName("dal05"); +guest = Guest.service(client).createObject(guest); +System.out.println("Virtual server ordered with ID: " + guest.getId()); +``` + +### Using Object Masks + +Object masks are a great way to reduce the number of API calls to traverse the data graph of an object. For example, +here's how by just asking for an account, you can retrieve all your VLANs, their datacenter, and the firewall rules that +are on them: + +```java +import com.softlayer.api.service.Account; +import com.softlayer.api.service.network.Vlan; +import com.softlayer.api.service.network.vlan.firewall.Rule; + +Account.Service service = Account.service(client); +service.withMask().networkVlans().vlanNumber(); +service.withMask().networkVlans().primaryRouter().datacenter().longName(); +service.withMask().networkVlans().firewallRules(). + orderValue(). + sourceIpAddress(). + sourceIpCidr(); + +for (Vlan vlan : service.getObject().getNetworkVlans()) { + for (Rule rule : vlan.getFirewallRules()) { + System.out.format("Rule %d on VLAN %d in %s has some restriction on subnet %s/%d\n", + rule.getOrderValue(), vlan.getVlanNumber(), + vlan.getPrimaryRouter().getDatacenter().getLongName(), + rule.getSourceIpAddress(), rule.getSourceIpCidr()); + } +} +``` + +All values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask +it is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer's +[string-based object mask format](http://sldn.softlayer.com/article/Object-Masks). A string or an instance of a mask +can be given directly by calling `setMask` on the service. Note, when object masks are added on a service object, they +will be sent with every service call unless removed via `clearMask` or overwritten via `withNewMask` or `setMask`. + +### Asynchronous Invocation + +All services also provide an asynchronous interface. This can be obtained from a service by calling `asAsync`. Here's an +example of getting all top level billing items and listing when they were created: + +```java +import java.util.List; +import com.softlayer.api.service.ResponseHandler; +import com.softlayer.api.service.Account; +import com.softlayer.api.service.billing.Item; + +Account.service(client).asAsync().getAllTopLevelBillingItems(new ResponseHandler>() { + @Override + public void onError(Exception ex) { + ex.printStackTrace(); + } + + @Override + public void onSuccess(List items) { + for (Item item : items) { + System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate()); + } + } +}).get(); +``` + +Using the default HTTP client, this runs the call in a separate thread and calls the handler parameter upon completion. +The `get` at the end basically makes it wait forever so the application doesn't exit out from under us. With the default +HTTP client the asynchronous invocations are handled by a simple thread pool that defaults to a cached thread pool that +creates daemon threads. It can be changed: + +```java +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import com.softlayer.api.service.RestApiClient; +import com.softlayer.api.service.http.ThreadPoolHttpClientFactory; +import com.softlayer.api.service.billing.Item; + +RestApiClient client = new RestApiClient(); +ExecutorService threadPool = Executors.newFixedThreadPool(3); +((ThreadPoolHttpClientFactory) client.getHttpClientFactory()).setThreadPool(threadPool); +``` + +Unlike using the default thread pool, you will be responsible for shutting down this overridden thread pool as +necessary. Other HTTP client implementations may handle asynchrony differently and not use thread pools at all. + +In addition to the callback-style above, can also get the response as a `Future`. Here's an example of waiting 10 +seconds to get all top level billing items: + +```java +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.Future; +import com.softlayer.api.service.Account; +import com.softlayer.api.service.billing.Item; + +Future> response = Account.service(client).asAsync().getAllTopLevelBillingItems(); +List items = response.get(10, TimeUnit.SECONDS); +for (Item item : items) { + System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate()); +} +``` + +### Thread Safety + +No class in this library is guaranteed to be thread-safe. Callers are expected to keep this in mind when developing +with the library and to never use the same `ApiClient` (or any other object created with it) concurrently across +threads. + +### Pagination + +Sometimes there is a need to get the responses from the SoftLayer API in a paginated way instead of all at once. This +can be done by utilizing result limits. A result limit can be passed in with the number of results requested and the +offset to start reading from. Requesting smaller amounts of data will increase the performance of the call. Here is an +example of obtaining the first 10 tickets and outputting the total: + +```java +import com.softlayer.api.ResultLimit; +import com.softlayer.api.service.Account; +import com.softlayer.api.service.Ticket; + +Account.Service service = Account.service(client); +service.setResultLimit(new ResultLimit(10)); +for (Ticket ticket : service.getTickets()) { + System.out.println("Got ticket " + ticket.getTitle()); +} +System.out.println("Total tickets on the account: " + service.getLastResponseTotalItemCount()); +``` + +The services are not guaranteed to be thread-safe on their own, so it is difficult to obtain the total with +`getLastResponseTotalItemCount` when using the service asynchronously. To assist with this when using the callback +style, the `ResponseHandlerWithHeaders` can be used instead of `ResponseHandler`. But the safest way is to only use a +single service per thread. + +### Differences from the API + +Due to restrictions on identifiers in Java, some properties, methods, classes, and packages will be named differently +from the naming used by the API. For example, an API property that starts with a number will be prepended with 'z'. +[Java keywords](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.9) that appear in identifiers may +also be replaced. + +## Building + +This project is intentionally provided without all of the service code. Normal Maven `install` and `package` commands +work properly and will regenerate the client. To specifically regenerate the Java service-related files, run: + + mvn generate-sources + +## Customization + +### Logging + +Logging the requests and response to stdout can be enabled by invoking `withLoggingEnabled` on the `RestApiClient`. In +order to log elsewhere, simply make your own implementation of `RestApiClient` with `logRequest` and `logResponse` +overridden. + +### HTTP Client + +The default HTTP client that is used is the JVM's native `HttpUrlConnection`. In order to create your own, alternative +implementation you must implement `com.softlayer.api.http.HttpClientFactory`. Once implemented, this can be explicitly +set on the `RestApiClient` by calling `setHttpClientFactory`. Instead of setting the factory manually, you can also +leverage Java's `ServiceLoader` mechanism to have it used by default. This involves adding the fully qualified class +name of your implementation on a single line in a file in the JAR at +`META-INF/com.softlayer.api.http.HttpClientFactory`. + +### JSON Marshalling + +The default JSON marshaller that is used is [Gson](https://code.google.com/p/google-gson/). In order to create your own, +alternative implementation you must implement `com.softlayer.api.json.JsonMarshallerFactyory`. Once implemented, this +can be explicitly set on the `RestApiClient` by calling `setJsonMarshallerFactory`. Instead of setting the factory +manually, you can also leverage Java's `ServiceLoader` mechanism to have it used by default. This involves adding the +fully qualified class name of your implementation on a single line in a file in the JAR at +`META-INF/com.softlayer.api.json.JsonMarshallerFactory`. + +## Copyright + +This software is Copyright (c) 2016 The SoftLayer Developer Network. See the bundled LICENSE file for more information. diff --git a/javascripts/scale.fix.js b/javascripts/scale.fix.js deleted file mode 100644 index 87a40ca..0000000 --- a/javascripts/scale.fix.js +++ /dev/null @@ -1,17 +0,0 @@ -var metas = document.getElementsByTagName('meta'); -var i; -if (navigator.userAgent.match(/iPhone/i)) { - for (i=0; i\r\n com.softlayer.api\r\n softlayer-api-client\r\n 0.2.3\r\n\r\n```\r\n\r\nNote, the client published to Maven is built upon version change of this project. It will contain the generated\r\nartifacts as of that time only. See \"Building\" for more information on how to regenerate the artifacts to get regular\r\nadditions to the SoftLayer API.\r\n\r\n### Creating a Client\r\n\r\nAll clients are instances of `ApiClient`. Currently there is only one implementation, the `RestApiClient`. Simply\r\ninstantiate it and provide your credentials:\r\n\r\n```java\r\nimport com.softlayer.api.*;\r\n\r\nApiClient client = new RestApiClient().withCredentials(\"my user\", \"my api key\");\r\n```\r\n\r\nIf the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the\r\n`RestApiClient`. By default it is set to `https://api.softlayer.com/rest/v3.1/`.\r\n\r\n### Making API Calls\r\n\r\nOnce a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer\r\naccount. A simple one is the `Account` service. Here's a call to get all of the hardware on the account:\r\n\r\n```java\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.Hardware;\r\n\r\nfor (Hardware hardware : Account.service(client).getHardware()) {\r\n System.out.println(\"Hardware: \" + hardware.getFullyQualifiedDomainName());\r\n}\r\n```\r\n\r\nSome calls on a service require an ID to know what object to act on. This can be obtained by passing in the numeric ID\r\ninto the `service` method or by calling `asService` on an object that has an ID. Here's an example of soft-rebooting a\r\nvirtual server with \"reboot-test\" as the hostname:\r\n\r\n```java\r\nimport com.softlayer.api.service.virtual.Guest;\r\n\r\nfor (Guest guest : Account.service(client).getVirtualGuests()) {\r\n if (\"reboot-test\".equals(guest.getHostname())) {\r\n guest.asService(client).rebootSoft();\r\n }\r\n}\r\n```\r\n\r\nSome calls require sending in data. This is done by just instantiating the object and populating the data. Here's an\r\nexample of ordering a new virtual server: (Note running this can charge your account)\r\n\r\n```java\r\nimport com.softlayer.api.service.virtual.Guest;\r\n\r\nGuest guest = new Guest();\r\nguest.setHostname(\"myhostname\");\r\nguest.setDomain(\"example.com\");\r\nguest.setStartCpus(1);\r\nguest.setMaxMemory(1024);\r\nguest.setHourlyBillingFlag(true);\r\nguest.setOperatingSystemReferenceCode(\"UBUNTU_LATEST\");\r\nguest.setLocalDiskFlag(false);\r\nguest.setDatacenter(new Location());\r\nguest.getDatacenter().setName(\"dal05\");\r\nguest = Guest.service(client).createObject(guest);\r\nSystem.out.println(\"Virtual server ordered with ID: \" + guest.getId());\r\n```\r\n\r\n### Using Object Masks\r\n\r\nObject masks are a great way to reduce the number of API calls to traverse the data graph of an object. For example,\r\nhere's how by just asking for an account, you can retrieve all your VLANs, their datacenter, and the firewall rules that\r\nare on them:\r\n\r\n```java\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.network.Vlan;\r\nimport com.softlayer.api.service.network.vlan.firewall.Rule;\r\n\r\nAccount.Service service = Account.service(client);\r\nservice.withMask().networkVlans().vlanNumber();\r\nservice.withMask().networkVlans().primaryRouter().datacenter().longName();\r\nservice.withMask().networkVlans().firewallRules().\r\n orderValue().\r\n sourceIpAddress().\r\n sourceIpCidr();\r\n\r\nfor (Vlan vlan : service.getObject().getNetworkVlans()) {\r\n for (Rule rule : vlan.getFirewallRules()) {\r\n System.out.format(\"Rule %d on VLAN %d in %s has some restriction on subnet %s/%d\\n\",\r\n rule.getOrderValue(), vlan.getVlanNumber(),\r\n vlan.getPrimaryRouter().getDatacenter().getLongName(),\r\n rule.getSourceIpAddress(), rule.getSourceIpCidr());\r\n }\r\n}\r\n```\r\n\r\nAll values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask\r\nit is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer's\r\n[string-based object mask format](http://sldn.softlayer.com/article/Object-Masks). A string or an instance of a mask\r\ncan be given directly by calling `setMask` on the service. Note, when object masks are added on a service object, they\r\nwill be sent with every service call unless removed via `clearMask` or overwritten via `withNewMask` or `setMask`.\r\n\r\n### Asynchronous Invocation\r\n\r\nAll services also provide an asynchronous interface. This can be obtained from a service by calling `asAsync`. Here's an\r\nexample of getting all top level billing items and listing when they were created:\r\n\r\n```java\r\nimport java.util.List;\r\nimport com.softlayer.api.service.ResponseHandler;\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.billing.Item;\r\n\r\nAccount.service(client).asAsync().getAllTopLevelBillingItems(new ResponseHandler>() {\r\n @Override\r\n public void onError(Exception ex) {\r\n ex.printStackTrace();\r\n }\r\n\r\n @Override\r\n public void onSuccess(List items) {\r\n for (Item item : items) {\r\n System.out.format(\"Billing item %s created on %s\\n\", item.getDescription(), item.getCreateDate());\r\n }\r\n }\r\n}).get();\r\n```\r\n\r\nUsing the default HTTP client, this runs the call in a separate thread and calls the handler parameter upon completion.\r\nThe `get` at the end basically makes it wait forever so the application doesn't exit out from under us. With the default\r\nHTTP client the asynchronous invocations are handled by a simple thread pool that defaults to a cached thread pool that\r\ncreates daemon threads. It can be changed:\r\n\r\n```java\r\nimport java.util.concurrent.Executors;\r\nimport java.util.concurrent.ExecutorService;\r\nimport com.softlayer.api.service.RestApiClient;\r\nimport com.softlayer.api.service.http.ThreadPoolHttpClientFactory;\r\nimport com.softlayer.api.service.billing.Item;\r\n\r\nRestApiClient client = new RestApiClient();\r\nExecutorService threadPool = Executors.newFixedThreadPool(3);\r\n((ThreadPoolHttpClientFactory) client.getHttpClientFactory()).setThreadPool(threadPool);\r\n```\r\n\r\nUnlike using the default thread pool, you will be responsible for shutting down this overridden thread pool as\r\nnecessary. Other HTTP client implementations may handle asynchrony differently and not use thread pools at all.\r\n\r\nIn addition to the callback-style above, can also get the response as a `Future`. Here's an example of waiting 10\r\nseconds to get all top level billing items:\r\n\r\n```java\r\nimport java.util.List;\r\nimport java.util.concurrent.TimeUnit;\r\nimport java.util.concurrent.Future;\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.billing.Item;\r\n\r\nFuture> response = Account.service(client).asAsync().getAllTopLevelBillingItems();\r\nList items = response.get(10, TimeUnit.SECONDS);\r\nfor (Item item : items) {\r\n System.out.format(\"Billing item %s created on %s\\n\", item.getDescription(), item.getCreateDate());\r\n}\r\n```\r\n\r\n### Thread Safety\r\n\r\nNo class in this library is guaranteed to be thread-safe. Callers are expected to keep this in mind when developing\r\nwith the library and to never use the same `ApiClient` (or any other object created with it) concurrently across\r\nthreads.\r\n\r\n### Pagination\r\n\r\nSometimes there is a need to get the responses from the SoftLayer API in a paginated way instead of all at once. This\r\ncan be done by utilizing result limits. A result limit can be passed in with the number of results requested and the\r\noffset to start reading from. Requesting smaller amounts of data will increase the performance of the call. Here is an\r\nexample of obtaining the first 10 tickets and outputting the total:\r\n\r\n```java\r\nimport com.softlayer.api.ResultLimit;\r\nimport com.softlayer.api.service.Account;\r\nimport com.softlayer.api.service.Ticket;\r\n\r\nAccount.Service service = Account.service(client);\r\nservice.setResultLimit(new ResultLimit(10));\r\nfor (Ticket ticket : service.getTickets()) {\r\n System.out.println(\"Got ticket \" + ticket.getTitle());\r\n}\r\nSystem.out.println(\"Total tickets on the account: \" + service.getLastResponseTotalItemCount());\r\n```\r\n\r\nThe services are not guaranteed to be thread-safe on their own, so it is difficult to obtain the total with\r\n`getLastResponseTotalItemCount` when using the service asynchronously. To assist with this when using the callback\r\nstyle, the `ResponseHandlerWithHeaders` can be used instead of `ResponseHandler`. But the safest way is to only use a\r\nsingle service per thread.\r\n\r\n### Differences from the API\r\n\r\nDue to restrictions on identifiers in Java, some properties, methods, classes, and packages will be named differently\r\nfrom the naming used by the API. For example, an API property that starts with a number will be prepended with 'z'.\r\n[Java keywords](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.9) that appear in identifiers may\r\nalso be replaced.\r\n\r\n## Building\r\n\r\nThis project is intentionally provided without all of the service code. Normal Maven `install` and `package` commands\r\nwork properly and will regenerate the client. To specifically regenerate the Java service-related files, run:\r\n\r\n mvn generate-sources\r\n\r\n## Customization\r\n\r\n### Logging\r\n\r\nLogging the requests and response to stdout can be enabled by invoking `withLoggingEnabled` on the `RestApiClient`. In\r\norder to log elsewhere, simply make your own implementation of `RestApiClient` with `logRequest` and `logResponse`\r\noverridden.\r\n\r\n### HTTP Client\r\n\r\nThe default HTTP client that is used is the JVM's native `HttpUrlConnection`. In order to create your own, alternative\r\nimplementation you must implement `com.softlayer.api.http.HttpClientFactory`. Once implemented, this can be explicitly\r\nset on the `RestApiClient` by calling `setHttpClientFactory`. Instead of setting the factory manually, you can also\r\nleverage Java's `ServiceLoader` mechanism to have it used by default. This involves adding the fully qualified class\r\nname of your implementation on a single line in a file in the JAR at\r\n`META-INF/com.softlayer.api.http.HttpClientFactory`.\r\n\r\n### JSON Marshalling\r\n\r\nThe default JSON marshaller that is used is [Gson](https://code.google.com/p/google-gson/). In order to create your own,\r\nalternative implementation you must implement `com.softlayer.api.json.JsonMarshallerFactyory`. Once implemented, this\r\ncan be explicitly set on the `RestApiClient` by calling `setJsonMarshallerFactory`. Instead of setting the factory\r\nmanually, you can also leverage Java's `ServiceLoader` mechanism to have it used by default. This involves adding the\r\nfully qualified class name of your implementation on a single line in a file in the JAR at\r\n`META-INF/com.softlayer.api.json.JsonMarshallerFactory`.\r\n\r\n## Copyright\r\n\r\nThis software is Copyright (c) 2016 The SoftLayer Developer Network. See the bundled LICENSE file for more information.\r\n", - "note": "Don't delete this file! It's used internally to help with page regeneration." -} \ No newline at end of file diff --git a/stylesheets/github-light.css b/stylesheets/github-light.css deleted file mode 100644 index 0c6b24d..0000000 --- a/stylesheets/github-light.css +++ /dev/null @@ -1,124 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 GitHub, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -.pl-c /* comment */ { - color: #969896; -} - -.pl-c1 /* constant, variable.other.constant, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header */, -.pl-s .pl-v /* string variable */ { - color: #0086b3; -} - -.pl-e /* entity */, -.pl-en /* entity.name */ { - color: #795da3; -} - -.pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */, -.pl-s .pl-s1 /* string source */ { - color: #333; -} - -.pl-ent /* entity.name.tag */ { - color: #63a35c; -} - -.pl-k /* keyword, storage, storage.type */ { - color: #a71d5d; -} - -.pl-s /* string */, -.pl-pds /* punctuation.definition.string, string.regexp.character-class */, -.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */, -.pl-sr /* string.regexp */, -.pl-sr .pl-cce /* string.regexp constant.character.escape */, -.pl-sr .pl-sre /* string.regexp source.ruby.embedded */, -.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ { - color: #183691; -} - -.pl-v /* variable */ { - color: #ed6a43; -} - -.pl-id /* invalid.deprecated */ { - color: #b52a1d; -} - -.pl-ii /* invalid.illegal */ { - color: #f8f8f8; - background-color: #b52a1d; -} - -.pl-sr .pl-cce /* string.regexp constant.character.escape */ { - font-weight: bold; - color: #63a35c; -} - -.pl-ml /* markup.list */ { - color: #693a17; -} - -.pl-mh /* markup.heading */, -.pl-mh .pl-en /* markup.heading entity.name */, -.pl-ms /* meta.separator */ { - font-weight: bold; - color: #1d3e81; -} - -.pl-mq /* markup.quote */ { - color: #008080; -} - -.pl-mi /* markup.italic */ { - font-style: italic; - color: #333; -} - -.pl-mb /* markup.bold */ { - font-weight: bold; - color: #333; -} - -.pl-md /* markup.deleted, meta.diff.header.from-file */ { - color: #bd2c00; - background-color: #ffecec; -} - -.pl-mi1 /* markup.inserted, meta.diff.header.to-file */ { - color: #55a532; - background-color: #eaffea; -} - -.pl-mdr /* meta.diff.range */ { - font-weight: bold; - color: #795da3; -} - -.pl-mo /* meta.output */ { - color: #1d3e81; -} - diff --git a/stylesheets/styles.css b/stylesheets/styles.css deleted file mode 100644 index 2e1768e..0000000 --- a/stylesheets/styles.css +++ /dev/null @@ -1,324 +0,0 @@ -@font-face { - font-family: 'Noto Sans'; - font-weight: 400; - font-style: normal; - src: url('../fonts/Noto-Sans-regular/Noto-Sans-regular.eot'); - src: url('../fonts/Noto-Sans-regular/Noto-Sans-regular.eot?#iefix') format('embedded-opentype'), - local('Noto Sans'), - local('Noto-Sans-regular'), - url('../fonts/Noto-Sans-regular/Noto-Sans-regular.woff2') format('woff2'), - url('../fonts/Noto-Sans-regular/Noto-Sans-regular.woff') format('woff'), - url('../fonts/Noto-Sans-regular/Noto-Sans-regular.ttf') format('truetype'), - url('../fonts/Noto-Sans-regular/Noto-Sans-regular.svg#NotoSans') format('svg'); -} - -@font-face { - font-family: 'Noto Sans'; - font-weight: 700; - font-style: normal; - src: url('../fonts/Noto-Sans-700/Noto-Sans-700.eot'); - src: url('../fonts/Noto-Sans-700/Noto-Sans-700.eot?#iefix') format('embedded-opentype'), - local('Noto Sans Bold'), - local('Noto-Sans-700'), - url('../fonts/Noto-Sans-700/Noto-Sans-700.woff2') format('woff2'), - url('../fonts/Noto-Sans-700/Noto-Sans-700.woff') format('woff'), - url('../fonts/Noto-Sans-700/Noto-Sans-700.ttf') format('truetype'), - url('../fonts/Noto-Sans-700/Noto-Sans-700.svg#NotoSans') format('svg'); -} - -@font-face { - font-family: 'Noto Sans'; - font-weight: 400; - font-style: italic; - src: url('../fonts/Noto-Sans-italic/Noto-Sans-italic.eot'); - src: url('../fonts/Noto-Sans-italic/Noto-Sans-italic.eot?#iefix') format('embedded-opentype'), - local('Noto Sans Italic'), - local('Noto-Sans-italic'), - url('../fonts/Noto-Sans-italic/Noto-Sans-italic.woff2') format('woff2'), - url('../fonts/Noto-Sans-italic/Noto-Sans-italic.woff') format('woff'), - url('../fonts/Noto-Sans-italic/Noto-Sans-italic.ttf') format('truetype'), - url('../fonts/Noto-Sans-italic/Noto-Sans-italic.svg#NotoSans') format('svg'); -} - -@font-face { - font-family: 'Noto Sans'; - font-weight: 700; - font-style: italic; - src: url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot'); - src: url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot?#iefix') format('embedded-opentype'), - local('Noto Sans Bold Italic'), - local('Noto-Sans-700italic'), - url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff2') format('woff2'), - url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff') format('woff'), - url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.ttf') format('truetype'), - url('../fonts/Noto-Sans-700italic/Noto-Sans-700italic.svg#NotoSans') format('svg'); -} - -body { - background-color: #fff; - padding:50px; - font: 14px/1.5 "Noto Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - color:#727272; - font-weight:400; -} - -h1, h2, h3, h4, h5, h6 { - color:#222; - margin:0 0 20px; -} - -p, ul, ol, table, pre, dl { - margin:0 0 20px; -} - -h1, h2, h3 { - line-height:1.1; -} - -h1 { - font-size:28px; -} - -h2 { - color:#393939; -} - -h3, h4, h5, h6 { - color:#494949; -} - -a { - color:#39c; - text-decoration:none; -} - -a:hover { - color:#069; -} - -a small { - font-size:11px; - color:#777; - margin-top:-0.3em; - display:block; -} - -a:hover small { - color:#777; -} - -.wrapper { - width:860px; - margin:0 auto; -} - -blockquote { - border-left:1px solid #e5e5e5; - margin:0; - padding:0 0 0 20px; - font-style:italic; -} - -code, pre { - font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal, Consolas, Liberation Mono, DejaVu Sans Mono, Courier New, monospace; - color:#333; - font-size:12px; -} - -pre { - padding:8px 15px; - background: #f8f8f8; - border-radius:5px; - border:1px solid #e5e5e5; - overflow-x: auto; -} - -table { - width:100%; - border-collapse:collapse; -} - -th, td { - text-align:left; - padding:5px 10px; - border-bottom:1px solid #e5e5e5; -} - -dt { - color:#444; - font-weight:700; -} - -th { - color:#444; -} - -img { - max-width:100%; -} - -header { - width:270px; - float:left; - position:fixed; - -webkit-font-smoothing:subpixel-antialiased; -} - -header ul { - list-style:none; - height:40px; - padding:0; - background: #f4f4f4; - border-radius:5px; - border:1px solid #e0e0e0; - width:270px; -} - -header li { - width:89px; - float:left; - border-right:1px solid #e0e0e0; - height:40px; -} - -header li:first-child a { - border-radius:5px 0 0 5px; -} - -header li:last-child a { - border-radius:0 5px 5px 0; -} - -header ul a { - line-height:1; - font-size:11px; - color:#999; - display:block; - text-align:center; - padding-top:6px; - height:34px; -} - -header ul a:hover { - color:#999; -} - -header ul a:active { - background-color:#f0f0f0; -} - -strong { - color:#222; - font-weight:700; -} - -header ul li + li + li { - border-right:none; - width:89px; -} - -header ul a strong { - font-size:14px; - display:block; - color:#222; -} - -section { - width:500px; - float:right; - padding-bottom:50px; -} - -small { - font-size:11px; -} - -hr { - border:0; - background:#e5e5e5; - height:1px; - margin:0 0 20px; -} - -footer { - width:270px; - float:left; - position:fixed; - bottom:50px; - -webkit-font-smoothing:subpixel-antialiased; -} - -@media print, screen and (max-width: 960px) { - - div.wrapper { - width:auto; - margin:0; - } - - header, section, footer { - float:none; - position:static; - width:auto; - } - - header { - padding-right:320px; - } - - section { - border:1px solid #e5e5e5; - border-width:1px 0; - padding:20px 0; - margin:0 0 20px; - } - - header a small { - display:inline; - } - - header ul { - position:absolute; - right:50px; - top:52px; - } -} - -@media print, screen and (max-width: 720px) { - body { - word-wrap:break-word; - } - - header { - padding:0; - } - - header ul, header p.view { - position:static; - } - - pre, code { - word-wrap:normal; - } -} - -@media print, screen and (max-width: 480px) { - body { - padding:15px; - } - - header ul { - width:99%; - } - - header li, header ul li + li + li { - width:33%; - } -} - -@media print { - body { - padding:0.4in; - font-size:12pt; - color:#444; - } -} From c51bf43679311eb6a6087ba060be3b003921b539 Mon Sep 17 00:00:00 2001 From: Cameron Porter Date: Thu, 2 Jan 2020 19:06:17 -0600 Subject: [PATCH 03/14] Manually update version to 0.2.8 --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index 3c0605f..037322e 100644 --- a/index.md +++ b/index.md @@ -31,7 +31,7 @@ To add the project you your Maven project, add the dependency: com.softlayer.api softlayer-api-client - 0.2.3 + 0.2.8 ``` From 7a3dc9cfb1ba76ee9385b65556210d5e9d2825d5 Mon Sep 17 00:00:00 2001 From: "Cameron Porter (via Travis CI)" Date: Thu, 9 Jan 2020 16:14:21 +0000 Subject: [PATCH 04/14] Deploy softlayer/softlayer-java to github.com/softlayer/softlayer-java.git:gh-pages --- _config.yml | 8 -- index.html | 153 +++++++++++++++++++++++++++++ index.md | 275 ---------------------------------------------------- 3 files changed, 153 insertions(+), 283 deletions(-) delete mode 100644 _config.yml create mode 100644 index.html delete mode 100644 index.md diff --git a/_config.yml b/_config.yml deleted file mode 100644 index f9dd549..0000000 --- a/_config.yml +++ /dev/null @@ -1,8 +0,0 @@ -title: Softlayer-java -description: SoftLayer API Client for Java -google_analytics: -show_downloads: true -theme: jekyll-theme-minimal - -gems: - - jekyll-mentions diff --git a/index.html b/index.html new file mode 100644 index 0000000..99b8eb9 --- /dev/null +++ b/index.html @@ -0,0 +1,153 @@ +

SoftLayer API Client for Java

+

Build Status Maven Central Javadocs

+

Introduction

+

This library provides a JVM client for the SoftLayer API. It has code generated and compiled via Maven. The client can work with any Java 8+ runtime. It uses the code generation project in gen/ to generate the service and type related code. Although likely to work in resource-constrained environments (i.e. Android, J2ME, etc), using this is not recommended; Use the REST API instead.

+

By default the HTTP client is the Java HttpUrlConnection and the JSON marshalling is done by Gson. Both of these pieces can be exchanged for alternative implementations (see below).

+

The examples/ project has sample uses of the API. It can be executed from Maven while inside the examples/ folder via a command:

+
mvn -q compile exec:java -Dexec.args="EXAMPLE_NAME API_USER API_KEY"
+

Where EXAMPLE_NAME is the unqualified class name of an example in the com.softlayer.api.example package (e.g. ListServers), API_USER is your API username, and API_KEY is your API key. NOTE: Some examples order virtual servers and may charge your account.

+

Using

+

Add the library as a dependency using your favorite build tooling.

+

Note that the published client library is built upon the state of the API at the time of the version's release. It will contain the generated artifacts as of that time only. See "Building" for more information on how to regenerate the artifacts to get regular additions to the SoftLayer API.

+

Maven

+
<dependency>
+  <groupId>com.softlayer.api</groupId>
+  <artifactId>softlayer-api-client</artifactId>
+  <version>0.2.8</version>
+</dependency>
+

Gradle

+
implementation 'com.softlayer.api:softlayer-api-client:0.2.8'
+

Kotlin

+
compile("com.softlayer.api:softlayer-api-client:0.2.8")
+

Creating a Client

+

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply instantiate it and provide your credentials:

+
import com.softlayer.api.*;
+
+ApiClient client = new RestApiClient().withCredentials("my user", "my api key");
+

If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the RestApiClient. By default it is set to https://api.softlayer.com/rest/v3.1/.

+

Making API Calls

+

Once a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer account. A simple one is the Account service. Here's a call to get all of the hardware on the account:

+
import com.softlayer.api.service.Account;
+import com.softlayer.api.service.Hardware;
+
+for (Hardware hardware : Account.service(client).getHardware()) {
+    System.out.println("Hardware: " + hardware.getFullyQualifiedDomainName());
+}
+

Some calls on a service require an ID to know what object to act on. This can be obtained by passing in the numeric ID into the service method or by calling asService on an object that has an ID. Here's an example of soft-rebooting a virtual server with "reboot-test" as the hostname:

+
import com.softlayer.api.service.virtual.Guest;
+
+for (Guest guest : Account.service(client).getVirtualGuests()) {
+    if ("reboot-test".equals(guest.getHostname())) {
+        guest.asService(client).rebootSoft();
+    }
+}
+

Some calls require sending in data. This is done by just instantiating the object and populating the data. Here's an example of ordering a new virtual server: (Note running this can charge your account)

+
import com.softlayer.api.service.virtual.Guest;
+
+Guest guest = new Guest();
+guest.setHostname("myhostname");
+guest.setDomain("example.com");
+guest.setStartCpus(1);
+guest.setMaxMemory(1024);
+guest.setHourlyBillingFlag(true);
+guest.setOperatingSystemReferenceCode("UBUNTU_LATEST");
+guest.setLocalDiskFlag(false);
+guest.setDatacenter(new Location());
+guest.getDatacenter().setName("dal05");
+guest = Guest.service(client).createObject(guest);
+System.out.println("Virtual server ordered with ID: " + guest.getId());
+

Using Object Masks

+

Object masks are a great way to reduce the number of API calls to traverse the data graph of an object. For example, here's how by just asking for an account, you can retrieve all your VLANs, their datacenter, and the firewall rules that are on them:

+
import com.softlayer.api.service.Account;
+import com.softlayer.api.service.network.Vlan;
+import com.softlayer.api.service.network.vlan.firewall.Rule;
+
+Account.Service service = Account.service(client);
+service.withMask().networkVlans().vlanNumber();
+service.withMask().networkVlans().primaryRouter().datacenter().longName();
+service.withMask().networkVlans().firewallRules().
+    orderValue().
+    sourceIpAddress().
+    sourceIpCidr();
+
+for (Vlan vlan : service.getObject().getNetworkVlans()) {
+    for (Rule rule : vlan.getFirewallRules()) {
+        System.out.format("Rule %d on VLAN %d in %s has some restriction on subnet %s/%d\n",
+            rule.getOrderValue(), vlan.getVlanNumber(),
+            vlan.getPrimaryRouter().getDatacenter().getLongName(),
+            rule.getSourceIpAddress(), rule.getSourceIpCidr());
+    }
+}
+

All values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask it is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer's string-based object mask format. A string or an instance of a mask can be given directly by calling setMask on the service. Note, when object masks are added on a service object, they will be sent with every service call unless removed via clearMask or overwritten via withNewMask or setMask.

+

Asynchronous Invocation

+

All services also provide an asynchronous interface. This can be obtained from a service by calling asAsync. Here's an example of getting all top level billing items and listing when they were created:

+
import java.util.List;
+import com.softlayer.api.service.ResponseHandler;
+import com.softlayer.api.service.Account;
+import com.softlayer.api.service.billing.Item;
+
+Account.service(client).asAsync().getAllTopLevelBillingItems(new ResponseHandler<List<Item>>() {
+    @Override
+    public void onError(Exception ex) {
+        ex.printStackTrace();
+    }
+
+    @Override
+    public void onSuccess(List<Item> items) {
+        for (Item item : items) {
+            System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate());
+        }
+    }
+}).get();
+

Using the default HTTP client, this runs the call in a separate thread and calls the handler parameter upon completion. The get at the end basically makes it wait forever so the application doesn't exit out from under us. With the default HTTP client the asynchronous invocations are handled by a simple thread pool that defaults to a cached thread pool that creates daemon threads. It can be changed:

+
import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import com.softlayer.api.service.RestApiClient;
+import com.softlayer.api.service.http.ThreadPoolHttpClientFactory;
+import com.softlayer.api.service.billing.Item;
+
+RestApiClient client = new RestApiClient();
+ExecutorService threadPool = Executors.newFixedThreadPool(3);
+((ThreadPoolHttpClientFactory) client.getHttpClientFactory()).setThreadPool(threadPool);
+

Unlike using the default thread pool, you will be responsible for shutting down this overridden thread pool as necessary. Other HTTP client implementations may handle asynchrony differently and not use thread pools at all.

+

In addition to the callback-style above, can also get the response as a Future. Here's an example of waiting 10 seconds to get all top level billing items:

+
import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.Future;
+import com.softlayer.api.service.Account;
+import com.softlayer.api.service.billing.Item;
+
+Future<List<Item>> response = Account.service(client).asAsync().getAllTopLevelBillingItems();
+List<Item> items = response.get(10, TimeUnit.SECONDS);
+for (Item item : items) {
+    System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate());
+}
+

Thread Safety

+

No class in this library is guaranteed to be thread-safe. Callers are expected to keep this in mind when developing with the library and to never use the same ApiClient (or any other object created with it) concurrently across threads.

+

Pagination

+

Sometimes there is a need to get the responses from the SoftLayer API in a paginated way instead of all at once. This can be done by utilizing result limits. A result limit can be passed in with the number of results requested and the offset to start reading from. Requesting smaller amounts of data will increase the performance of the call. Here is an example of obtaining the first 10 tickets and outputting the total:

+
import com.softlayer.api.ResultLimit;
+import com.softlayer.api.service.Account;
+import com.softlayer.api.service.Ticket;
+
+Account.Service service = Account.service(client);
+service.setResultLimit(new ResultLimit(10));
+for (Ticket ticket : service.getTickets()) {
+    System.out.println("Got ticket " + ticket.getTitle());
+}
+System.out.println("Total tickets on the account: " + service.getLastResponseTotalItemCount());
+

The services are not guaranteed to be thread-safe on their own, so it is difficult to obtain the total with getLastResponseTotalItemCount when using the service asynchronously. To assist with this when using the callback style, the ResponseHandlerWithHeaders can be used instead of ResponseHandler. But the safest way is to only use a single service per thread.

+

Differences from the API

+

Due to restrictions on identifiers in Java, some properties, methods, classes, and packages will be named differently from the naming used by the API. For example, an API property that starts with a number will be prepended with 'z'. Java keywords that appear in identifiers may also be replaced.

+

Building

+

This project is intentionally provided without all of the service code. Normal Maven install and package commands work properly and will regenerate the client. To specifically regenerate the Java service-related files, run:

+
mvn generate-sources
+

Customization

+

Logging

+

Logging the requests and response to stdout can be enabled by invoking withLoggingEnabled on the RestApiClient. In order to log elsewhere, simply make your own implementation of RestApiClient with logRequest and logResponse overridden.

+

HTTP Client

+

The default HTTP client that is used is the JVM's native HttpUrlConnection. In order to create your own, alternative implementation you must implement com.softlayer.api.http.HttpClientFactory. Once implemented, this can be explicitly set on the RestApiClient by calling setHttpClientFactory. Instead of setting the factory manually, you can also leverage Java's ServiceLoader mechanism to have it used by default. This involves adding the fully qualified class name of your implementation on a single line in a file in the JAR at META-INF/com.softlayer.api.http.HttpClientFactory.

+

JSON Marshalling

+

The default JSON marshaller that is used is Gson. In order to create your own, alternative implementation you must implement com.softlayer.api.json.JsonMarshallerFactory. Once implemented, this can be explicitly set on the RestApiClient by calling setJsonMarshallerFactory. Instead of setting the factory manually, you can also leverage Java's ServiceLoader mechanism to have it used by default. This involves adding the fully qualified class name of your implementation on a single line in a file in the JAR at META-INF/com.softlayer.api.json.JsonMarshallerFactory.

+ +

This software is Copyright (c) 2020 The SoftLayer Developer Network. See the bundled LICENSE file for more information.

diff --git a/index.md b/index.md deleted file mode 100644 index 037322e..0000000 --- a/index.md +++ /dev/null @@ -1,275 +0,0 @@ -# SoftLayer API Client for Java - -[![Build Status](https://travis-ci.org/softlayer/softlayer-java.svg)](https://travis-ci.org/softlayer/softlayer-java) - -## Introduction - -This library provides a JVM client for the [SoftLayer API](http://sldn.softlayer.com/article/SoftLayer-API-Overview). It -has code generated and compiled via Maven. The client can work with any Java 6+ runtime. It uses the code generation -project in `gen/` to generate the service and type related code. Although likely to work in resource-constrained -environments (i.e. Android, J2ME, etc), using this is not recommended; Use the -[REST](http://sldn.softlayer.com/article/REST) API instead. - -By default the HTTP client is the Java `HttpUrlConnection` and the JSON marshalling is done by -[Gson](https://code.google.com/p/google-gson/). Both of these pieces can be exchanged for alternative implementations -(see below). - -The `examples/` project has sample uses of the API. It can be executed from Maven while inside the `examples/` folder -via a command: - - mvn -q compile exec:java -Dexec.args="EXAMPLE_NAME API_USER API_KEY" - -Where `EXAMPLE_NAME` is the unqualified class name of an example in the `com.softlayer.api.example` package (e.g. -`ListServers`), `API_USER` is your API username, and `API_KEY` is your API key. NOTE: Some examples order virtual -servers and may charge your account. - -## Using - -To add the project you your Maven project, add the dependency: - -```xml - - com.softlayer.api - softlayer-api-client - 0.2.8 - -``` - -Note, the client published to Maven is built upon version change of this project. It will contain the generated -artifacts as of that time only. See "Building" for more information on how to regenerate the artifacts to get regular -additions to the SoftLayer API. - -### Creating a Client - -All clients are instances of `ApiClient`. Currently there is only one implementation, the `RestApiClient`. Simply -instantiate it and provide your credentials: - -```java -import com.softlayer.api.*; - -ApiClient client = new RestApiClient().withCredentials("my user", "my api key"); -``` - -If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the -`RestApiClient`. By default it is set to `https://api.softlayer.com/rest/v3.1/`. - -### Making API Calls - -Once a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer -account. A simple one is the `Account` service. Here's a call to get all of the hardware on the account: - -```java -import com.softlayer.api.service.Account; -import com.softlayer.api.service.Hardware; - -for (Hardware hardware : Account.service(client).getHardware()) { - System.out.println("Hardware: " + hardware.getFullyQualifiedDomainName()); -} -``` - -Some calls on a service require an ID to know what object to act on. This can be obtained by passing in the numeric ID -into the `service` method or by calling `asService` on an object that has an ID. Here's an example of soft-rebooting a -virtual server with "reboot-test" as the hostname: - -```java -import com.softlayer.api.service.virtual.Guest; - -for (Guest guest : Account.service(client).getVirtualGuests()) { - if ("reboot-test".equals(guest.getHostname())) { - guest.asService(client).rebootSoft(); - } -} -``` - -Some calls require sending in data. This is done by just instantiating the object and populating the data. Here's an -example of ordering a new virtual server: (Note running this can charge your account) - -```java -import com.softlayer.api.service.virtual.Guest; - -Guest guest = new Guest(); -guest.setHostname("myhostname"); -guest.setDomain("example.com"); -guest.setStartCpus(1); -guest.setMaxMemory(1024); -guest.setHourlyBillingFlag(true); -guest.setOperatingSystemReferenceCode("UBUNTU_LATEST"); -guest.setLocalDiskFlag(false); -guest.setDatacenter(new Location()); -guest.getDatacenter().setName("dal05"); -guest = Guest.service(client).createObject(guest); -System.out.println("Virtual server ordered with ID: " + guest.getId()); -``` - -### Using Object Masks - -Object masks are a great way to reduce the number of API calls to traverse the data graph of an object. For example, -here's how by just asking for an account, you can retrieve all your VLANs, their datacenter, and the firewall rules that -are on them: - -```java -import com.softlayer.api.service.Account; -import com.softlayer.api.service.network.Vlan; -import com.softlayer.api.service.network.vlan.firewall.Rule; - -Account.Service service = Account.service(client); -service.withMask().networkVlans().vlanNumber(); -service.withMask().networkVlans().primaryRouter().datacenter().longName(); -service.withMask().networkVlans().firewallRules(). - orderValue(). - sourceIpAddress(). - sourceIpCidr(); - -for (Vlan vlan : service.getObject().getNetworkVlans()) { - for (Rule rule : vlan.getFirewallRules()) { - System.out.format("Rule %d on VLAN %d in %s has some restriction on subnet %s/%d\n", - rule.getOrderValue(), vlan.getVlanNumber(), - vlan.getPrimaryRouter().getDatacenter().getLongName(), - rule.getSourceIpAddress(), rule.getSourceIpCidr()); - } -} -``` - -All values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask -it is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer's -[string-based object mask format](http://sldn.softlayer.com/article/Object-Masks). A string or an instance of a mask -can be given directly by calling `setMask` on the service. Note, when object masks are added on a service object, they -will be sent with every service call unless removed via `clearMask` or overwritten via `withNewMask` or `setMask`. - -### Asynchronous Invocation - -All services also provide an asynchronous interface. This can be obtained from a service by calling `asAsync`. Here's an -example of getting all top level billing items and listing when they were created: - -```java -import java.util.List; -import com.softlayer.api.service.ResponseHandler; -import com.softlayer.api.service.Account; -import com.softlayer.api.service.billing.Item; - -Account.service(client).asAsync().getAllTopLevelBillingItems(new ResponseHandler>() { - @Override - public void onError(Exception ex) { - ex.printStackTrace(); - } - - @Override - public void onSuccess(List items) { - for (Item item : items) { - System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate()); - } - } -}).get(); -``` - -Using the default HTTP client, this runs the call in a separate thread and calls the handler parameter upon completion. -The `get` at the end basically makes it wait forever so the application doesn't exit out from under us. With the default -HTTP client the asynchronous invocations are handled by a simple thread pool that defaults to a cached thread pool that -creates daemon threads. It can be changed: - -```java -import java.util.concurrent.Executors; -import java.util.concurrent.ExecutorService; -import com.softlayer.api.service.RestApiClient; -import com.softlayer.api.service.http.ThreadPoolHttpClientFactory; -import com.softlayer.api.service.billing.Item; - -RestApiClient client = new RestApiClient(); -ExecutorService threadPool = Executors.newFixedThreadPool(3); -((ThreadPoolHttpClientFactory) client.getHttpClientFactory()).setThreadPool(threadPool); -``` - -Unlike using the default thread pool, you will be responsible for shutting down this overridden thread pool as -necessary. Other HTTP client implementations may handle asynchrony differently and not use thread pools at all. - -In addition to the callback-style above, can also get the response as a `Future`. Here's an example of waiting 10 -seconds to get all top level billing items: - -```java -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.Future; -import com.softlayer.api.service.Account; -import com.softlayer.api.service.billing.Item; - -Future> response = Account.service(client).asAsync().getAllTopLevelBillingItems(); -List items = response.get(10, TimeUnit.SECONDS); -for (Item item : items) { - System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate()); -} -``` - -### Thread Safety - -No class in this library is guaranteed to be thread-safe. Callers are expected to keep this in mind when developing -with the library and to never use the same `ApiClient` (or any other object created with it) concurrently across -threads. - -### Pagination - -Sometimes there is a need to get the responses from the SoftLayer API in a paginated way instead of all at once. This -can be done by utilizing result limits. A result limit can be passed in with the number of results requested and the -offset to start reading from. Requesting smaller amounts of data will increase the performance of the call. Here is an -example of obtaining the first 10 tickets and outputting the total: - -```java -import com.softlayer.api.ResultLimit; -import com.softlayer.api.service.Account; -import com.softlayer.api.service.Ticket; - -Account.Service service = Account.service(client); -service.setResultLimit(new ResultLimit(10)); -for (Ticket ticket : service.getTickets()) { - System.out.println("Got ticket " + ticket.getTitle()); -} -System.out.println("Total tickets on the account: " + service.getLastResponseTotalItemCount()); -``` - -The services are not guaranteed to be thread-safe on their own, so it is difficult to obtain the total with -`getLastResponseTotalItemCount` when using the service asynchronously. To assist with this when using the callback -style, the `ResponseHandlerWithHeaders` can be used instead of `ResponseHandler`. But the safest way is to only use a -single service per thread. - -### Differences from the API - -Due to restrictions on identifiers in Java, some properties, methods, classes, and packages will be named differently -from the naming used by the API. For example, an API property that starts with a number will be prepended with 'z'. -[Java keywords](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.9) that appear in identifiers may -also be replaced. - -## Building - -This project is intentionally provided without all of the service code. Normal Maven `install` and `package` commands -work properly and will regenerate the client. To specifically regenerate the Java service-related files, run: - - mvn generate-sources - -## Customization - -### Logging - -Logging the requests and response to stdout can be enabled by invoking `withLoggingEnabled` on the `RestApiClient`. In -order to log elsewhere, simply make your own implementation of `RestApiClient` with `logRequest` and `logResponse` -overridden. - -### HTTP Client - -The default HTTP client that is used is the JVM's native `HttpUrlConnection`. In order to create your own, alternative -implementation you must implement `com.softlayer.api.http.HttpClientFactory`. Once implemented, this can be explicitly -set on the `RestApiClient` by calling `setHttpClientFactory`. Instead of setting the factory manually, you can also -leverage Java's `ServiceLoader` mechanism to have it used by default. This involves adding the fully qualified class -name of your implementation on a single line in a file in the JAR at -`META-INF/com.softlayer.api.http.HttpClientFactory`. - -### JSON Marshalling - -The default JSON marshaller that is used is [Gson](https://code.google.com/p/google-gson/). In order to create your own, -alternative implementation you must implement `com.softlayer.api.json.JsonMarshallerFactyory`. Once implemented, this -can be explicitly set on the `RestApiClient` by calling `setJsonMarshallerFactory`. Instead of setting the factory -manually, you can also leverage Java's `ServiceLoader` mechanism to have it used by default. This involves adding the -fully qualified class name of your implementation on a single line in a file in the JAR at -`META-INF/com.softlayer.api.json.JsonMarshallerFactory`. - -## Copyright - -This software is Copyright (c) 2016 The SoftLayer Developer Network. See the bundled LICENSE file for more information. From ce5d3811eda6a1613877344d22ecc2e453a3010b Mon Sep 17 00:00:00 2001 From: "Cameron Porter (via Travis CI)" Date: Tue, 21 Jan 2020 21:18:48 +0000 Subject: [PATCH 05/14] Deploy softlayer/softlayer-java to github.com/softlayer/softlayer-java.git:gh-pages --- index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 99b8eb9..c1d917c 100644 --- a/index.html +++ b/index.html @@ -13,12 +13,12 @@

Maven

<dependency>
   <groupId>com.softlayer.api</groupId>
   <artifactId>softlayer-api-client</artifactId>
-  <version>0.2.8</version>
+  <version>0.2.9</version>
 </dependency>

Gradle

-
implementation 'com.softlayer.api:softlayer-api-client:0.2.8'
+
implementation 'com.softlayer.api:softlayer-api-client:0.2.9'

Kotlin

-
compile("com.softlayer.api:softlayer-api-client:0.2.8")
+
compile("com.softlayer.api:softlayer-api-client:0.2.9")

Creating a Client

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply instantiate it and provide your credentials:

import com.softlayer.api.*;

From 67991fccdc6c998b703dbc4304889f645cf3e6f5 Mon Sep 17 00:00:00 2001
From: "Cameron Porter (via Travis CI)" 
Date: Wed, 25 Mar 2020 15:18:25 +0000
Subject: [PATCH 06/14] Deploy softlayer/softlayer-java to
 github.com/softlayer/softlayer-java.git:gh-pages

---
 index.html | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/index.html b/index.html
index c1d917c..93da171 100644
--- a/index.html
+++ b/index.html
@@ -24,7 +24,10 @@ 

Creating a Client

import com.softlayer.api.*;
 
 ApiClient client = new RestApiClient().withCredentials("my user", "my api key");
-

If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the RestApiClient. By default it is set to https://api.softlayer.com/rest/v3.1/.

+

If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the RestApiClient. By default it is set to the public API endpoint, https://api.softlayer.com/rest/v3.1/.

+

If you are using the classic infrastructure private network, you can communicate with the API over that network by using the service URL instead:

+
ApiClient client = new RestApiClient(RestApiClient.BASE_SERVICE_URL)
+    .withCredentials("my user", "my api key");

Making API Calls

Once a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer account. A simple one is the Account service. Here's a call to get all of the hardware on the account:

import com.softlayer.api.service.Account;

From 80a941e79018175fd4bee39e3099485602494563 Mon Sep 17 00:00:00 2001
From: "Cameron Porter (via Travis CI)" 
Date: Wed, 25 Mar 2020 17:17:40 +0000
Subject: [PATCH 07/14] Deploy softlayer/softlayer-java to
 github.com/softlayer/softlayer-java.git:gh-pages

---
 index.html | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/index.html b/index.html
index 93da171..d0ab043 100644
--- a/index.html
+++ b/index.html
@@ -13,12 +13,12 @@ 

Maven

<dependency>
   <groupId>com.softlayer.api</groupId>
   <artifactId>softlayer-api-client</artifactId>
-  <version>0.2.9</version>
+  <version>0.3.0</version>
 </dependency>

Gradle

-
implementation 'com.softlayer.api:softlayer-api-client:0.2.9'
+
implementation 'com.softlayer.api:softlayer-api-client:0.3.0'

Kotlin

-
compile("com.softlayer.api:softlayer-api-client:0.2.9")
+
compile("com.softlayer.api:softlayer-api-client:0.3.0")

Creating a Client

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply instantiate it and provide your credentials:

import com.softlayer.api.*;

From 0e2f450e0b038d79e366abed048e51b2fe775a39 Mon Sep 17 00:00:00 2001
From: "Cameron Porter (via Travis CI)" 
Date: Wed, 25 Mar 2020 20:02:23 +0000
Subject: [PATCH 08/14] Deploy softlayer/softlayer-java to
 github.com/softlayer/softlayer-java.git:gh-pages

---
 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/index.html b/index.html
index d0ab043..7d2bf5d 100644
--- a/index.html
+++ b/index.html
@@ -1,5 +1,5 @@
 

SoftLayer API Client for Java

-

Build Status Maven Central Javadocs

+

Build Status Maven Central Javadocs

Introduction

This library provides a JVM client for the SoftLayer API. It has code generated and compiled via Maven. The client can work with any Java 8+ runtime. It uses the code generation project in gen/ to generate the service and type related code. Although likely to work in resource-constrained environments (i.e. Android, J2ME, etc), using this is not recommended; Use the REST API instead.

By default the HTTP client is the Java HttpUrlConnection and the JSON marshalling is done by Gson. Both of these pieces can be exchanged for alternative implementations (see below).

From 12118fdfead42dedd4f13000508be5e883ee2d88 Mon Sep 17 00:00:00 2001 From: "Christopher Gallo (via Travis CI)" Date: Mon, 9 Nov 2020 23:41:23 +0000 Subject: [PATCH 09/14] Deploy softlayer/softlayer-java to github.com/softlayer/softlayer-java.git:gh-pages --- index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 7d2bf5d..f8fb47a 100644 --- a/index.html +++ b/index.html @@ -13,12 +13,12 @@

Maven

<dependency>
   <groupId>com.softlayer.api</groupId>
   <artifactId>softlayer-api-client</artifactId>
-  <version>0.3.0</version>
+  <version>0.3.1</version>
 </dependency>

Gradle

-
implementation 'com.softlayer.api:softlayer-api-client:0.3.0'
+
implementation 'com.softlayer.api:softlayer-api-client:0.3.1'

Kotlin

-
compile("com.softlayer.api:softlayer-api-client:0.3.0")
+
compile("com.softlayer.api:softlayer-api-client:0.3.1")

Creating a Client

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply instantiate it and provide your credentials:

import com.softlayer.api.*;

From 5ad1b56753fa1429e0b07bea2d42f69e5e8edd5e Mon Sep 17 00:00:00 2001
From: "cmp (via Travis CI)" 
Date: Wed, 9 Dec 2020 00:33:39 +0000
Subject: [PATCH 10/14] Deploy softlayer/softlayer-java to
 github.com/softlayer/softlayer-java.git:gh-pages

---
 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/index.html b/index.html
index f8fb47a..0cb3be2 100644
--- a/index.html
+++ b/index.html
@@ -1,5 +1,5 @@
 

SoftLayer API Client for Java

-

Build Status Maven Central Javadocs

+

Java CI Maven Central Javadocs

Introduction

This library provides a JVM client for the SoftLayer API. It has code generated and compiled via Maven. The client can work with any Java 8+ runtime. It uses the code generation project in gen/ to generate the service and type related code. Although likely to work in resource-constrained environments (i.e. Android, J2ME, etc), using this is not recommended; Use the REST API instead.

By default the HTTP client is the Java HttpUrlConnection and the JSON marshalling is done by Gson. Both of these pieces can be exchanged for alternative implementations (see below).

From ac1035481acc29e6f5ef7fbb2d2e00e39bf0377f Mon Sep 17 00:00:00 2001 From: "Christopher Gallo (via Travis CI)" Date: Thu, 14 Jan 2021 21:45:41 +0000 Subject: [PATCH 11/14] Deploy softlayer/softlayer-java to github.com/softlayer/softlayer-java.git:gh-pages --- index.html | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 0cb3be2..b24eafd 100644 --- a/index.html +++ b/index.html @@ -13,17 +13,23 @@

Maven

<dependency>
   <groupId>com.softlayer.api</groupId>
   <artifactId>softlayer-api-client</artifactId>
-  <version>0.3.1</version>
+  <version>0.3.2</version>
 </dependency>

Gradle

-
implementation 'com.softlayer.api:softlayer-api-client:0.3.1'
+
implementation 'com.softlayer.api:softlayer-api-client:0.3.2'

Kotlin

-
compile("com.softlayer.api:softlayer-api-client:0.3.1")
+
compile("com.softlayer.api:softlayer-api-client:0.3.2")

Creating a Client

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply instantiate it and provide your credentials:

+

Username and API Key

+

For using a Classic Infrastructure or IBM Cloud API key. When using the IBM Cloud Api key, your username is the literal string apikey, more information about that can be found on the SLDN Authenticating to the SoftLayer API article.

import com.softlayer.api.*;
 
 ApiClient client = new RestApiClient().withCredentials("my user", "my api key");
+

Access Token

+

Information on how to get a temoprary api token can be found on the SLDN Authenticating to the SoftLayer API article.

+
import com.softlayer.api.*;
+ApiClient client = new RestApiClient().withBearerToken("qqqqwwwweeeaaassddd....");

If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the RestApiClient. By default it is set to the public API endpoint, https://api.softlayer.com/rest/v3.1/.

If you are using the classic infrastructure private network, you can communicate with the API over that network by using the service URL instead:

ApiClient client = new RestApiClient(RestApiClient.BASE_SERVICE_URL)
@@ -153,4 +159,4 @@ 

HTTP Client

JSON Marshalling

The default JSON marshaller that is used is Gson. In order to create your own, alternative implementation you must implement com.softlayer.api.json.JsonMarshallerFactory. Once implemented, this can be explicitly set on the RestApiClient by calling setJsonMarshallerFactory. Instead of setting the factory manually, you can also leverage Java's ServiceLoader mechanism to have it used by default. This involves adding the fully qualified class name of your implementation on a single line in a file in the JAR at META-INF/com.softlayer.api.json.JsonMarshallerFactory.

-

This software is Copyright (c) 2020 The SoftLayer Developer Network. See the bundled LICENSE file for more information.

+

This software is Copyright (c) 2021 The SoftLayer Developer Network. See the bundled LICENSE file for more information.

From 5177aab96fa0988f5114597e78277d7f3544edcb Mon Sep 17 00:00:00 2001 From: "cmp (via Travis CI)" Date: Thu, 21 Jan 2021 23:13:28 +0000 Subject: [PATCH 12/14] Deploy softlayer/softlayer-java to github.com/softlayer/softlayer-java.git:gh-pages --- index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index b24eafd..1173423 100644 --- a/index.html +++ b/index.html @@ -23,9 +23,10 @@

Creating a Client

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply instantiate it and provide your credentials:

Username and API Key

For using a Classic Infrastructure or IBM Cloud API key. When using the IBM Cloud Api key, your username is the literal string apikey, more information about that can be found on the SLDN Authenticating to the SoftLayer API article.

+

:warning: Make sure to avoid hard coding your username and API key when using the client! Always pull credentials from the environment, secure config, or other source.

import com.softlayer.api.*;
 
-ApiClient client = new RestApiClient().withCredentials("my user", "my api key");
+ApiClient client = new RestApiClient().withCredentials(myUser, myApiKey);

Access Token

Information on how to get a temoprary api token can be found on the SLDN Authenticating to the SoftLayer API article.

import com.softlayer.api.*;

From 443cdcf9577ee013a504fe417cb3ee7b73019190 Mon Sep 17 00:00:00 2001
From: camporter 
Date: Wed, 15 Sep 2021 18:52:03 +0000
Subject: [PATCH 13/14] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20so?=
 =?UTF-8?q?ftlayer/softlayer-java@7a337d9d8a72a6bb517105ce9c4e986e84ce9502?=
 =?UTF-8?q?=20=F0=9F=9A=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 index.html | 250 ++++++++++++++++++++++++++---------------------------
 1 file changed, 125 insertions(+), 125 deletions(-)

diff --git a/index.html b/index.html
index 1173423..11d81a2 100644
--- a/index.html
+++ b/index.html
@@ -1,154 +1,154 @@
 

SoftLayer API Client for Java

-

Java CI Maven Central Javadocs

+

Java CI Maven Central Javadocs

Introduction

-

This library provides a JVM client for the SoftLayer API. It has code generated and compiled via Maven. The client can work with any Java 8+ runtime. It uses the code generation project in gen/ to generate the service and type related code. Although likely to work in resource-constrained environments (i.e. Android, J2ME, etc), using this is not recommended; Use the REST API instead.

-

By default the HTTP client is the Java HttpUrlConnection and the JSON marshalling is done by Gson. Both of these pieces can be exchanged for alternative implementations (see below).

+

This library provides a JVM client for the SoftLayer API. It has code generated and compiled via Maven. The client can work with any Java 8+ runtime. It uses the code generation project in gen/ to generate the service and type related code. Although likely to work in resource-constrained environments (i.e. Android, J2ME, etc), using this is not recommended; Use the REST API instead.

+

By default the HTTP client is the Java HttpUrlConnection and the JSON marshalling is done by Gson. Both of these pieces can be exchanged for alternative implementations (see below).

The examples/ project has sample uses of the API. It can be executed from Maven while inside the examples/ folder via a command:

mvn -q compile exec:java -Dexec.args="EXAMPLE_NAME API_USER API_KEY"

Where EXAMPLE_NAME is the unqualified class name of an example in the com.softlayer.api.example package (e.g. ListServers), API_USER is your API username, and API_KEY is your API key. NOTE: Some examples order virtual servers and may charge your account.

Using

Add the library as a dependency using your favorite build tooling.

-

Note that the published client library is built upon the state of the API at the time of the version's release. It will contain the generated artifacts as of that time only. See "Building" for more information on how to regenerate the artifacts to get regular additions to the SoftLayer API.

+

Note that the published client library is built upon the state of the API at the time of the version’s release. It will contain the generated artifacts as of that time only. See “Building” for more information on how to regenerate the artifacts to get regular additions to the SoftLayer API.

Maven

-
<dependency>
-  <groupId>com.softlayer.api</groupId>
-  <artifactId>softlayer-api-client</artifactId>
-  <version>0.3.2</version>
-</dependency>
+

Gradle

-
implementation 'com.softlayer.api:softlayer-api-client:0.3.2'
+
implementation 'com.softlayer.api:softlayer-api-client:0.3.3'

Kotlin

-
compile("com.softlayer.api:softlayer-api-client:0.3.2")
+

Creating a Client

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply instantiate it and provide your credentials:

Username and API Key

For using a Classic Infrastructure or IBM Cloud API key. When using the IBM Cloud Api key, your username is the literal string apikey, more information about that can be found on the SLDN Authenticating to the SoftLayer API article.

:warning: Make sure to avoid hard coding your username and API key when using the client! Always pull credentials from the environment, secure config, or other source.

-
import com.softlayer.api.*;
-
-ApiClient client = new RestApiClient().withCredentials(myUser, myApiKey);
+

Access Token

Information on how to get a temoprary api token can be found on the SLDN Authenticating to the SoftLayer API article.

-
import com.softlayer.api.*;
-ApiClient client = new RestApiClient().withBearerToken("qqqqwwwweeeaaassddd....");
-

If the end point isn't at the normal SoftLayer API, you can provide the prefix to the constructor of the RestApiClient. By default it is set to the public API endpoint, https://api.softlayer.com/rest/v3.1/.

+ +

If the end point isn’t at the normal SoftLayer API, you can provide the prefix to the constructor of the RestApiClient. By default, it is set to the public API endpoint, https://api.softlayer.com/rest/v3.1/.

If you are using the classic infrastructure private network, you can communicate with the API over that network by using the service URL instead:

-
ApiClient client = new RestApiClient(RestApiClient.BASE_SERVICE_URL)
-    .withCredentials("my user", "my api key");
+

Making API Calls

-

Once a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer account. A simple one is the Account service. Here's a call to get all of the hardware on the account:

-
import com.softlayer.api.service.Account;
-import com.softlayer.api.service.Hardware;
-
-for (Hardware hardware : Account.service(client).getHardware()) {
-    System.out.println("Hardware: " + hardware.getFullyQualifiedDomainName());
-}
-

Some calls on a service require an ID to know what object to act on. This can be obtained by passing in the numeric ID into the service method or by calling asService on an object that has an ID. Here's an example of soft-rebooting a virtual server with "reboot-test" as the hostname:

-
import com.softlayer.api.service.virtual.Guest;
-
-for (Guest guest : Account.service(client).getVirtualGuests()) {
-    if ("reboot-test".equals(guest.getHostname())) {
-        guest.asService(client).rebootSoft();
-    }
-}
-

Some calls require sending in data. This is done by just instantiating the object and populating the data. Here's an example of ordering a new virtual server: (Note running this can charge your account)

-
import com.softlayer.api.service.virtual.Guest;
-
-Guest guest = new Guest();
-guest.setHostname("myhostname");
-guest.setDomain("example.com");
-guest.setStartCpus(1);
-guest.setMaxMemory(1024);
-guest.setHourlyBillingFlag(true);
-guest.setOperatingSystemReferenceCode("UBUNTU_LATEST");
-guest.setLocalDiskFlag(false);
-guest.setDatacenter(new Location());
-guest.getDatacenter().setName("dal05");
-guest = Guest.service(client).createObject(guest);
-System.out.println("Virtual server ordered with ID: " + guest.getId());
+

Once a client is created, it can be used to access services. There are hundreds of services to control your SoftLayer account. A simple one is the Account service. Here’s a call to get all of the hardware on the account:

+ +

Some calls on a service require an ID to know what object to act on. This can be obtained by passing in the numeric ID into the service method or by calling asService on an object that has an ID. Here’s an example of soft-rebooting a virtual server with “reboot-test” as the hostname:

+ +

Some calls require sending in data. This is done by just instantiating the object and populating the data. Here’s an example of ordering a new virtual server: (Note running this can charge your account)

+

Using Object Masks

-

Object masks are a great way to reduce the number of API calls to traverse the data graph of an object. For example, here's how by just asking for an account, you can retrieve all your VLANs, their datacenter, and the firewall rules that are on them:

-
import com.softlayer.api.service.Account;
-import com.softlayer.api.service.network.Vlan;
-import com.softlayer.api.service.network.vlan.firewall.Rule;
-
-Account.Service service = Account.service(client);
-service.withMask().networkVlans().vlanNumber();
-service.withMask().networkVlans().primaryRouter().datacenter().longName();
-service.withMask().networkVlans().firewallRules().
-    orderValue().
-    sourceIpAddress().
-    sourceIpCidr();
-
-for (Vlan vlan : service.getObject().getNetworkVlans()) {
-    for (Rule rule : vlan.getFirewallRules()) {
-        System.out.format("Rule %d on VLAN %d in %s has some restriction on subnet %s/%d\n",
-            rule.getOrderValue(), vlan.getVlanNumber(),
-            vlan.getPrimaryRouter().getDatacenter().getLongName(),
-            rule.getSourceIpAddress(), rule.getSourceIpCidr());
-    }
-}
-

All values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask it is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer's string-based object mask format. A string or an instance of a mask can be given directly by calling setMask on the service. Note, when object masks are added on a service object, they will be sent with every service call unless removed via clearMask or overwritten via withNewMask or setMask.

+

Object masks are a great way to reduce the number of API calls to traverse the data graph of an object. For example, here’s how by just asking for an account, you can retrieve all your VLANs, their datacenter, and the firewall rules that are on them:

+ +

All values of a type can be masked upon. If a value represents a primitive or collection of primitives, the same mask it is called on is returned. Otherwise the mask of the other type is given. These translate into SoftLayer’s string-based object mask format. A string or an instance of a mask can be given directly by calling setMask on the service. Note, when object masks are added on a service object, they will be sent with every service call unless removed via clearMask or overwritten via withNewMask or setMask.

Asynchronous Invocation

-

All services also provide an asynchronous interface. This can be obtained from a service by calling asAsync. Here's an example of getting all top level billing items and listing when they were created:

-
import java.util.List;
-import com.softlayer.api.service.ResponseHandler;
-import com.softlayer.api.service.Account;
-import com.softlayer.api.service.billing.Item;
-
-Account.service(client).asAsync().getAllTopLevelBillingItems(new ResponseHandler<List<Item>>() {
-    @Override
-    public void onError(Exception ex) {
-        ex.printStackTrace();
-    }
-
-    @Override
-    public void onSuccess(List<Item> items) {
-        for (Item item : items) {
-            System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate());
-        }
-    }
-}).get();
-

Using the default HTTP client, this runs the call in a separate thread and calls the handler parameter upon completion. The get at the end basically makes it wait forever so the application doesn't exit out from under us. With the default HTTP client the asynchronous invocations are handled by a simple thread pool that defaults to a cached thread pool that creates daemon threads. It can be changed:

-
import java.util.concurrent.Executors;
-import java.util.concurrent.ExecutorService;
-import com.softlayer.api.service.RestApiClient;
-import com.softlayer.api.service.http.ThreadPoolHttpClientFactory;
-import com.softlayer.api.service.billing.Item;
-
-RestApiClient client = new RestApiClient();
-ExecutorService threadPool = Executors.newFixedThreadPool(3);
-((ThreadPoolHttpClientFactory) client.getHttpClientFactory()).setThreadPool(threadPool);
+

All services also provide an asynchronous interface. This can be obtained from a service by calling asAsync. Here’s an example of getting all top level billing items and listing when they were created:

+ +

Using the default HTTP client, this runs the call in a separate thread and calls the handler parameter upon completion. The get at the end basically makes it wait forever so the application doesn’t exit out from under us. With the default HTTP client the asynchronous invocations are handled by a simple thread pool that defaults to a cached thread pool that creates daemon threads. It can be changed:

+

Unlike using the default thread pool, you will be responsible for shutting down this overridden thread pool as necessary. Other HTTP client implementations may handle asynchrony differently and not use thread pools at all.

-

In addition to the callback-style above, can also get the response as a Future. Here's an example of waiting 10 seconds to get all top level billing items:

-
import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.Future;
-import com.softlayer.api.service.Account;
-import com.softlayer.api.service.billing.Item;
-
-Future<List<Item>> response = Account.service(client).asAsync().getAllTopLevelBillingItems();
-List<Item> items = response.get(10, TimeUnit.SECONDS);
-for (Item item : items) {
-    System.out.format("Billing item %s created on %s\n", item.getDescription(), item.getCreateDate());
-}
+

In addition to the callback-style above, can also get the response as a Future. Here’s an example of waiting 10 seconds to get all top level billing items:

+

Thread Safety

No class in this library is guaranteed to be thread-safe. Callers are expected to keep this in mind when developing with the library and to never use the same ApiClient (or any other object created with it) concurrently across threads.

Pagination

Sometimes there is a need to get the responses from the SoftLayer API in a paginated way instead of all at once. This can be done by utilizing result limits. A result limit can be passed in with the number of results requested and the offset to start reading from. Requesting smaller amounts of data will increase the performance of the call. Here is an example of obtaining the first 10 tickets and outputting the total:

-
import com.softlayer.api.ResultLimit;
-import com.softlayer.api.service.Account;
-import com.softlayer.api.service.Ticket;
-
-Account.Service service = Account.service(client);
-service.setResultLimit(new ResultLimit(10));
-for (Ticket ticket : service.getTickets()) {
-    System.out.println("Got ticket " + ticket.getTitle());
-}
-System.out.println("Total tickets on the account: " + service.getLastResponseTotalItemCount());
+

The services are not guaranteed to be thread-safe on their own, so it is difficult to obtain the total with getLastResponseTotalItemCount when using the service asynchronously. To assist with this when using the callback style, the ResponseHandlerWithHeaders can be used instead of ResponseHandler. But the safest way is to only use a single service per thread.

Differences from the API

-

Due to restrictions on identifiers in Java, some properties, methods, classes, and packages will be named differently from the naming used by the API. For example, an API property that starts with a number will be prepended with 'z'. Java keywords that appear in identifiers may also be replaced.

+

Due to restrictions on identifiers in Java, some properties, methods, classes, and packages will be named differently from the naming used by the API. For example, an API property that starts with a number will be prepended with ‘z’. Java keywords that appear in identifiers may also be replaced.

Building

This project is intentionally provided without all of the service code. Normal Maven install and package commands work properly and will regenerate the client. To specifically regenerate the Java service-related files, run:

mvn generate-sources
@@ -156,8 +156,8 @@

Customization

Logging

Logging the requests and response to stdout can be enabled by invoking withLoggingEnabled on the RestApiClient. In order to log elsewhere, simply make your own implementation of RestApiClient with logRequest and logResponse overridden.

HTTP Client

-

The default HTTP client that is used is the JVM's native HttpUrlConnection. In order to create your own, alternative implementation you must implement com.softlayer.api.http.HttpClientFactory. Once implemented, this can be explicitly set on the RestApiClient by calling setHttpClientFactory. Instead of setting the factory manually, you can also leverage Java's ServiceLoader mechanism to have it used by default. This involves adding the fully qualified class name of your implementation on a single line in a file in the JAR at META-INF/com.softlayer.api.http.HttpClientFactory.

+

The default HTTP client that is used is the JVM’s native HttpUrlConnection. In order to create your own, alternative implementation you must implement com.softlayer.api.http.HttpClientFactory. Once implemented, this can be explicitly set on the RestApiClient by calling setHttpClientFactory. Instead of setting the factory manually, you can also leverage Java’s ServiceLoader mechanism to have it used by default. This involves adding the fully qualified class name of your implementation on a single line in a file in the JAR at META-INF/com.softlayer.api.http.HttpClientFactory.

JSON Marshalling

-

The default JSON marshaller that is used is Gson. In order to create your own, alternative implementation you must implement com.softlayer.api.json.JsonMarshallerFactory. Once implemented, this can be explicitly set on the RestApiClient by calling setJsonMarshallerFactory. Instead of setting the factory manually, you can also leverage Java's ServiceLoader mechanism to have it used by default. This involves adding the fully qualified class name of your implementation on a single line in a file in the JAR at META-INF/com.softlayer.api.json.JsonMarshallerFactory.

+

The default JSON marshaller that is used is Gson. In order to create your own, alternative implementation you must implement com.softlayer.api.json.JsonMarshallerFactory. Once implemented, this can be explicitly set on the RestApiClient by calling setJsonMarshallerFactory. Instead of setting the factory manually, you can also leverage Java’s ServiceLoader mechanism to have it used by default. This involves adding the fully qualified class name of your implementation on a single line in a file in the JAR at META-INF/com.softlayer.api.json.JsonMarshallerFactory.

This software is Copyright (c) 2021 The SoftLayer Developer Network. See the bundled LICENSE file for more information.

From 2da06e60c9f2598f32b87089e94fbf1191c2c23b Mon Sep 17 00:00:00 2001 From: camporter Date: Fri, 17 Dec 2021 18:15:16 +0000 Subject: [PATCH 14/14] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20so?= =?UTF-8?q?ftlayer/softlayer-java@ecc49545c1d487ae1261d3b4e6e30ce0817d1c28?= =?UTF-8?q?=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 11d81a2..2cdb393 100644 --- a/index.html +++ b/index.html @@ -13,12 +13,12 @@

Maven

Gradle

-
implementation 'com.softlayer.api:softlayer-api-client:0.3.3'
+
implementation 'com.softlayer.api:softlayer-api-client:0.3.4'

Kotlin

- +

Creating a Client

All clients are instances of ApiClient. Currently there is only one implementation, the RestApiClient. Simply instantiate it and provide your credentials:

Username and API Key

@@ -28,7 +28,7 @@

Username and API Key

ApiClient client = new RestApiClient().withCredentials(myUser, myApiKey);

Access Token

-

Information on how to get a temoprary api token can be found on the SLDN Authenticating to the SoftLayer API article.

+

Information on how to get a temporary api token can be found on the SLDN Authenticating to the SoftLayer API article.

If the end point isn’t at the normal SoftLayer API, you can provide the prefix to the constructor of the RestApiClient. By default, it is set to the public API endpoint, https://api.softlayer.com/rest/v3.1/.