diff --git a/README.md b/README.md index f380208..b983200 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,14 @@ To get started you will also user API signing keys and credentials for the user To use the code to manage objects in OCI you will need to : -Create an AuthenticationProcessor (com.oracle.timg.oci.authentication) - this does the security work for you, speciy the OCI configuration file section to use for the connection and optionall the OCI region to work on (by defual it will sue the region in the config file) +Create an AuthenticationProcessor (com.oracle.timg.oci.authentication) - this does the security work for you, specify the OCI configuration file section to use for the connection and optionally the OCI region to work on (by default it will use the region in the config file) From there use the other processor classes as needed, these will all need the AuthenticationProcessor you created as part of their consructor. ### Prerequisites -You will need a development environment with Java (17 is the cersion Im using, earlier versions may not be supported by the OCI Java SDK). +You will need a development environment with Java (21 is the version I'm currently using, earlier versions may not be supported by the OCI Java SDK). I also use Maven to build this and to manage the dependencies, but if you have other mechanisms feel free. @@ -40,7 +40,7 @@ This is a **very** limited set of OCI services that are being wrapped here, over This project is open source. Please submit your contributions by forking this repository and submitting a pull request! Oracle appreciates any contributions that are made by the open source community. ## License -Copyright (c) 2024 Oracle and/or its affiliates. +Copyright (c) 2025 Oracle and/or its affiliates. Licensed under the Universal Permissive License (UPL), Version 1.0. diff --git a/oci-java-sdk-simple-wrappers-testing/.classpath b/oci-java-sdk-simple-wrappers-testing/.classpath new file mode 100644 index 0000000..6fe96f9 --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/.classpath @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oci-java-sdk-simple-wrappers-testing/.factorypath b/oci-java-sdk-simple-wrappers-testing/.factorypath new file mode 100644 index 0000000..e6eef8b --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/.factorypath @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oci-java-sdk-simple-wrappers-testing/.gitignore b/oci-java-sdk-simple-wrappers-testing/.gitignore new file mode 100644 index 0000000..d4111ff --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/.gitignore @@ -0,0 +1,2 @@ +/.settings/ +/target/ diff --git a/oci-java-sdk-simple-wrappers-testing/.project b/oci-java-sdk-simple-wrappers-testing/.project new file mode 100644 index 0000000..3e3f276 --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/.project @@ -0,0 +1,23 @@ + + + oci-java-sdk-simple-wrappers-testing + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/oci-java-sdk-simple-wrappers-testing/README.txt b/oci-java-sdk-simple-wrappers-testing/README.txt new file mode 100644 index 0000000..393263a --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/README.txt @@ -0,0 +1,4 @@ +While the dependencies below are built using Maven the resulting jar files are not in a public Maven repo, you will need to get them and setup your development setup appropriately to access these. +All of these are eclipse projects. +This is a set of examples that use the OCI API Wrappers - see the git hub repo at https://github.com/oracle-devrel/oci-java-sdk-simple-wrappers +To handle the Command line interactions this uses some utility classes to handle the users command line interactions, the project containing those is at https://github.com/atimgraves/timg-utilities diff --git a/oci-java-sdk-simple-wrappers-testing/pom.xml b/oci-java-sdk-simple-wrappers-testing/pom.xml new file mode 100644 index 0000000..065ff01 --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/pom.xml @@ -0,0 +1,38 @@ + + 4.0.0 + com.oracle.timg.demo + oci-java-sdk-simple-wrappers-testing + 0.0.1-SNAPSHOT + OciTesting + + UTF-8 + 1.0.1 + 1.0.9 + 17 + ${maven.compiler.source} + + + + com.oracle.timg.demo + oci-java-sdk-simple-wrappers + ${version.ocicore} + + + com.google.guava + guava + 32.0.1-jre + + + org.json + json + 20231013 + + + timg.utilities + TimGUtilities + ${version.timgutils} + + + \ No newline at end of file diff --git a/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/identity/ListCompartmentsAndStreams.java b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/identity/ListCompartmentsAndStreams.java new file mode 100644 index 0000000..755567b --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/identity/ListCompartmentsAndStreams.java @@ -0,0 +1,100 @@ +/*Copyright (c) 2023 Oracle and/or its affiliates. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software (each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at +a minimum a reference to the UPL must 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. + */ +package com.oracle.timg.demo.examples.identity; + +import java.io.IOException; +import java.util.stream.Collectors; + +import com.oracle.bmc.auth.AuthenticationDetailsProvider; +import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; +import com.oracle.bmc.identity.Identity; +import com.oracle.bmc.identity.IdentityClient; +import com.oracle.bmc.identity.model.Compartment; +import com.oracle.bmc.identity.model.Compartment.LifecycleState; +import com.oracle.bmc.identity.requests.ListCompartmentsRequest; +import com.oracle.bmc.identity.responses.ListCompartmentsResponse; +import com.oracle.bmc.streaming.StreamAdminClient; +import com.oracle.bmc.streaming.requests.ListStreamsRequest; +import com.oracle.bmc.streaming.responses.ListStreamsResponse; + +import lombok.extern.slf4j.Slf4j; + +//Have Lombok create a logger for us +@Slf4j +public class ListCompartmentsAndStreams { + + public static void main(String[] args) { + AuthenticationDetailsProvider provider; + try { + provider = new ConfigFileAuthenticationDetailsProvider("DEFAULT"); + } catch (IOException e) { + e.printStackTrace(); + return; + } + StreamAdminClient streamAdminClient = new StreamAdminClient(provider); + String compartmentId = provider.getTenantId(); + try (Identity identityClient = new IdentityClient(provider);) { + System.out.println("ListCompartments: with compartmentIdInSubtree == true"); + String nextPageToken = null; + do { + ListCompartmentsResponse response = identityClient + .listCompartments(ListCompartmentsRequest.builder().limit(50).compartmentId(compartmentId) + .compartmentIdInSubtree(Boolean.TRUE).page(nextPageToken).build()); + + for (Compartment compartment : response.getItems()) { + LifecycleState state = compartment.getLifecycleState(); + if (state == LifecycleState.Active) { + System.out.println(compartment); + listStreamsInCompartment(compartment.getId(), streamAdminClient); + } + } + nextPageToken = response.getOpcNextPage(); + } while (nextPageToken != null); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void listStreamsInCompartment(String id, StreamAdminClient streamAdminClient) { + ListStreamsRequest request = ListStreamsRequest.builder().compartmentId(id).build(); + + ListStreamsResponse listResponse = streamAdminClient.listStreams(request); + String streams = listResponse.getItems().stream().map(resp -> resp.toString()).collect(Collectors.joining(",")); + System.out.println("Resp = " + streams); + } + +} diff --git a/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/identity/ListCompartmentsInTennancy.java b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/identity/ListCompartmentsInTennancy.java new file mode 100644 index 0000000..0bd7227 --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/identity/ListCompartmentsInTennancy.java @@ -0,0 +1,100 @@ +/*Copyright (c) 2023 Oracle and/or its affiliates. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software (each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at +a minimum a reference to the UPL must 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. + */ +package com.oracle.timg.demo.examples.identity; + +import java.io.IOException; +import java.util.stream.Collectors; + +import com.oracle.bmc.auth.AuthenticationDetailsProvider; +import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; +import com.oracle.bmc.identity.Identity; +import com.oracle.bmc.identity.IdentityClient; +import com.oracle.bmc.identity.model.Compartment; +import com.oracle.bmc.identity.model.Compartment.LifecycleState; +import com.oracle.bmc.identity.requests.ListCompartmentsRequest; +import com.oracle.bmc.identity.responses.ListCompartmentsResponse; +import com.oracle.bmc.streaming.StreamAdminClient; +import com.oracle.bmc.streaming.requests.ListStreamsRequest; +import com.oracle.bmc.streaming.responses.ListStreamsResponse; + +import lombok.extern.slf4j.Slf4j; + +//Have Lombok create a logger for us +@Slf4j +public class ListCompartmentsInTennancy { + + public static void main(String[] args) { + AuthenticationDetailsProvider provider; + try { + provider = new ConfigFileAuthenticationDetailsProvider("DEFAULT"); + } catch (IOException e) { + e.printStackTrace(); + return; + } + StreamAdminClient streamAdminClient = new StreamAdminClient(provider); + String compartmentId = provider.getTenantId(); + try (Identity identityClient = new IdentityClient(provider);) { + System.out.println("ListCompartments: with compartmentIdInSubtree == true"); + String nextPageToken = null; + do { + ListCompartmentsResponse response = identityClient + .listCompartments(ListCompartmentsRequest.builder().limit(50).compartmentId(compartmentId) + .compartmentIdInSubtree(Boolean.TRUE).page(nextPageToken).build()); + + for (Compartment compartment : response.getItems()) { + LifecycleState state = compartment.getLifecycleState(); + if (state == LifecycleState.Active) { + System.out.println(compartment); + listStreamsInCompartment(compartment.getId(), streamAdminClient); + } + } + nextPageToken = response.getOpcNextPage(); + } while (nextPageToken != null); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void listStreamsInCompartment(String id, StreamAdminClient streamAdminClient) { + ListStreamsRequest request = ListStreamsRequest.builder().compartmentId(id).build(); + + ListStreamsResponse listResponse = streamAdminClient.listStreams(request); + String streams = listResponse.getItems().stream().map(resp -> resp.toString()).collect(Collectors.joining(",")); + System.out.println("Resp = " + streams); + } + +} diff --git a/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/instances/CreateInstance.java b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/instances/CreateInstance.java new file mode 100644 index 0000000..a2cf2d8 --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/instances/CreateInstance.java @@ -0,0 +1,246 @@ +/*Copyright (c) 2023 Oracle and/or its affiliates. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software (each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at +a minimum a reference to the UPL must 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. + */ +package com.oracle.timg.demo.examples.instances; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +import com.oracle.bmc.core.model.Image; +import com.oracle.bmc.core.model.Instance; +import com.oracle.bmc.core.model.InternetGateway; +import com.oracle.bmc.core.model.Shape; +import com.oracle.bmc.core.model.Subnet; +import com.oracle.bmc.core.model.Vcn; +import com.oracle.bmc.core.model.Vnic; +import com.oracle.bmc.core.model.VnicAttachment; +import com.oracle.bmc.identity.model.AvailabilityDomain; +import com.oracle.bmc.identity.model.Compartment; +import com.oracle.timg.oci.authentication.AuthenticationProcessor; +import com.oracle.timg.oci.compute.ComputeProcessor; +import com.oracle.timg.oci.identity.IdentityProcessor; +import com.oracle.timg.oci.networking.VCNProcessor; + +import lombok.extern.slf4j.Slf4j; +import timgutilities.textio.ChoiceDescription; +import timgutilities.textio.ChoiceDescriptionData; +import timgutilities.textio.TextIOUtils; +import timgutilities.textio.TextIOUtils.NUM_TYPE; + +@Slf4j +public class CreateInstance { + + private static final String OPERATING_SYSTEM = "Oracle Linux"; + + public final static void main(String args[]) throws IllegalArgumentException, Exception { + String confAuthName = TextIOUtils.getString("What's the oci config file section to use ?", "LONDON"); + AuthenticationProcessor ap = new AuthenticationProcessor(confAuthName); + // look for a compartment + log.info("Gathering basic information"); + IdentityProcessor ip = new IdentityProcessor(ap); + + String homeRegion = ip.getHomeRegion(); + String configRegion = ap.getConfigFileRegionName(); + List regions = new LinkedList<>(ip.listRegions(true, configRegion)); + log.info("Region from config is " + configRegion); + log.info("Home region is " + homeRegion); + log.info("Other regions are " + regions); + regions.add(0, homeRegion); + regions.add(0, configRegion); + + String workingRegion = TextIOUtils + .getStringChoice( + "Please chose a region to operate in, your config file region is " + configRegion + + " your home region is " + homeRegion + " - only subscribed regions are listed", + regions); + + if (!homeRegion.equals(workingRegion)) { + ap.setRegionName(workingRegion); + ip.setRegion(workingRegion); + } + + String parentCompartmentOCID; + boolean useTenancyRootForParent = TextIOUtils.getYN("Use tenancy root as the parent compartment ?", false); + // allow one level of navigation down + if (useTenancyRootForParent) { + parentCompartmentOCID = ap.getTenancyOCID(); + } else { + List childCompartments = ip.listChildCompartments(); + if (childCompartments.size() == 0) { + log.info( + "No child compartments of tenancy root to use as the sub compartment, will use tenancy root as parent of child compartment"); + parentCompartmentOCID = ap.getTenancyOCID(); + } else { + ChoiceDescriptionData compartmentsChoices = new ChoiceDescriptionData<>( + childCompartments.stream().map(c -> new ChoiceDescription<>(c.getName(), c)).toList()); + compartmentsChoices.setDoSort(true); + compartmentsChoices.addAbandonOption("Revert to using tenancy for parent compartment", false); + Compartment child = TextIOUtils.getParamChoice( + "Please chose the compartment to use as the parent ofthe compartment you will create", + compartmentsChoices); + if (child == null) { + log.info("OK, using tenancy root as parent compartment"); + parentCompartmentOCID = ap.getTenancyOCID(); + } else { + parentCompartmentOCID = child.getId(); + log.info("OK, using " + child.getName() + " with OCID " + parentCompartmentOCID + + " as the parent of the new compartment "); + } + } + } + String compartmentName = TextIOUtils.getString("What compartment name for these resources ?", "demoinstance"); + Compartment c = ip.locateCompartment(compartmentName, parentCompartmentOCID); + if (c == null) { + log.info("Cannot locate compartment " + compartmentName + " going to try create it"); + String compartmentDescription = TextIOUtils.getString( + "What description do you want to use for the compartment ?", compartmentName + " compartment"); + c = ip.createCompartment(compartmentName, compartmentDescription, parentCompartmentOCID); + } + log.info("Compartment OCID is " + c.getId() + "named " + c.getName() + " it's parent is " + + c.getCompartmentId()); + + log.info("Capturing data on the networking"); + // try to create the VCN for this compartment + String vcnName = TextIOUtils.getString("What name do you want to use for the VCN ?", "demoinstance"); + VCNProcessor vp = new VCNProcessor(ap); + Vcn vcn = vp.locateVCN(vcnName, c); + if (vcn == null) { + log.info("Cannot locate VCN named " + vcnName + " goibng to try to create it"); + String vcnCidr = TextIOUtils.getString("What CIDR do you want to use for the VCN ?", "10.0.0.0/16"); + vcn = vp.createVcn(vcnName, vcnCidr, c); + } + log.info("VCN OCID is " + vcn.getId() + " in compartment ocid " + vcn.getCompartmentId()); + + String internetGwName = TextIOUtils.getString("What name do you want to use for the internet gateway ?", + "demoinstance"); + InternetGateway gateway = vp.locateInternetGateway(internetGwName, c, vcn); + if (gateway == null) { + log.info("Cannot locate internet gateway named " + internetGwName + " going to create it"); + gateway = vp.createInternetGateway(internetGwName, c, vcn); + } + + log.info("Internet gateway OCID is " + gateway.getId() + " in compartment ocid " + vcn.getCompartmentId()); + vp.addInternetGatewayToDefaultRouteTable(vcn, gateway); + + String subnetName = TextIOUtils.getString("What name do you want to use for the subnet ?", "demoinstance"); + Subnet s = vp.locateSubnet(subnetName, c, vcn); + if (s == null) { + log.info("Cannot locate subnet named " + subnetName + " going to try and create it"); + String subnetCidr = TextIOUtils.getString("What CIDR do you want to use for the subnet ?", "10.0.0.0/24"); + Boolean privateOnly = TextIOUtils.getYN("Does this subnet block public internet facing instances ?", false); + s = vp.createSubnet(subnetName, subnetCidr, vcn, c, privateOnly); + } + log.info("Subnet ODIC is " + s.getId() + " in compartment ocid " + vcn.getCompartmentId()); + + // now the compute client work itself + + log.info("Capturing data on the compute instance"); + String instanceName = TextIOUtils.getString("What name do you want to use for the compute instance name ?", + "demoinstance"); + ComputeProcessor cp = new ComputeProcessor(ap); + // Get the AD + List ads = ip.getAvailabilityDomains(c); + ChoiceDescriptionData adChoices = new ChoiceDescriptionData<>( + ads.stream().map(ad -> new ChoiceDescription<>(ad.getName(), ad)).collect(Collectors.toList())); + adChoices.setDoSort(true); + AvailabilityDomain ad = TextIOUtils.getParamChoice("Please chose the availability domain for your instance", + adChoices); + log.info("Using AD " + ad.getName()); + + Instance i = cp.locateInstance(instanceName, c, ad); + if (i == null) { + log.info("Unable to locate an existing instance called " + instanceName + " in AD " + ad.getName() + + " in Compartment " + c.getName() + " Creating it"); + + List shapes = cp.getVmShapes(ad, c); + ChoiceDescriptionData shapeChoices = new ChoiceDescriptionData<>(shapes.stream() + .map(shape -> new ChoiceDescription<>(shape.getShape(), shape)).collect(Collectors.toList())); + shapeChoices.setDoSort(true); + Shape shape = TextIOUtils.getParamChoice("Please chose the shape to create your instance", shapeChoices); + log.info("Using Shape " + shape.getShape()); + + // flex shapes need more info + int ocpuCount = 0; + float memCount = 0; + if (shape.getIsFlexible()) { + log.info("You have chosen a flexible shape, additional, information is needed"); + float gbuPerOcpu = shape.getMemoryOptions().getDefaultPerOcpuInGBs(); + int minOcpu = shape.getOcpuOptions().getMin().intValue(); + int maxOcpu = shape.getOcpuOptions().getMax().intValue(); + ocpuCount = TextIOUtils.getInt("How many OCPUs do you want, this script will allocate " + gbuPerOcpu + + " GB of memory per OCPU selected", NUM_TYPE.RANGE, minOcpu, maxOcpu, 4); + memCount = gbuPerOcpu * ocpuCount; + log.info("Will create an instance with " + ocpuCount + " OCPUs and " + memCount + "GB memory"); + } + + List images = cp.getImages(shape, c, OPERATING_SYSTEM); + ChoiceDescriptionData imageChoices = new ChoiceDescriptionData<>(images.stream() + .map(image -> new ChoiceDescription<>(image.getDisplayName(), image)).collect(Collectors.toList())); + imageChoices.setDoSort(true); + Image image = TextIOUtils.getParamChoice("Please chose the image to create your instance", imageChoices); + log.info("Using Image " + image.getDisplayName()); + + String sshPubKeyFile = TextIOUtils.getFileMatching( + "Please enter the location of the ssh public key file (must end in .pub)", "pub$", + "/Users/tg13456/Desktop/OCI Settings/default/sshkey.pub"); + String sshKey = Files.readString(Paths.get(sshPubKeyFile)); + log.info("Loaded public ssh key from " + sshPubKeyFile); + + log.info("Creating instance, this may take a short time"); + + if (shape.getIsFlexible()) { + i = cp.createInstance(instanceName, c, ad, shape, image, s, sshKey, null, ocpuCount, memCount); + } else { + i = cp.createInstance(instanceName, c, ad, shape, image, s, sshKey, null); + } + + log.info("Created instance " + i.getId()); + + } + log.info("Instance Public IPs"); + List vnicAttachments = cp.getInstanceVnicAttachements(i); + + vnicAttachments.forEach(vnicAttachment -> { + Vnic vnic = vp.getVnicFromAttachement(vnicAttachment); + log.info(vnic.getPublicIp()); + }); + + log.info("Instance details\n" + cp.printInstance(i, vp.getClient())); + } +} diff --git a/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/instances/DeleteInstance.java b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/instances/DeleteInstance.java new file mode 100644 index 0000000..4151926 --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/instances/DeleteInstance.java @@ -0,0 +1,136 @@ +/*Copyright (c) 2023 Oracle and/or its affiliates. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software (each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at +a minimum a reference to the UPL must 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. + */ +package com.oracle.timg.demo.examples.instances; + +import java.util.List; +import java.util.stream.Collectors; + +import com.oracle.bmc.core.model.Instance; +import com.oracle.bmc.core.model.InternetGateway; +import com.oracle.bmc.core.model.VnicAttachment; +import com.oracle.bmc.identity.model.AvailabilityDomain; +import com.oracle.bmc.identity.model.Compartment; +import com.oracle.timg.oci.authentication.AuthenticationProcessor; +import com.oracle.timg.oci.compute.ComputeProcessor; +import com.oracle.timg.oci.identity.IdentityProcessor; +import com.oracle.timg.oci.networking.VCNProcessor; + +import lombok.extern.slf4j.Slf4j; +import timgutilities.textio.ChoiceDescription; +import timgutilities.textio.ChoiceDescriptionData; +import timgutilities.textio.TextIOUtils; + +@Slf4j +public class DeleteInstance { + + public final static void main(String args[]) throws IllegalArgumentException, Exception { + String confAuthName = TextIOUtils.getString("What's the oci config file section to use ?", "DEFAULT"); + AuthenticationProcessor ap = new AuthenticationProcessor(confAuthName); + // look for a compartment + log.info("Gathering basic information"); + String compartmentName = TextIOUtils.getString("What compartment name for these resources ?", "demoinstance"); + IdentityProcessor ip = new IdentityProcessor(ap); + Compartment c = ip.locateCompartment(compartmentName); + if (c == null) { + log.info("Cannot locate compartment " + compartmentName + " unable to proceed"); + return; + } + + log.info("Gathering instance information"); + + // Get the AD + List ads = ip.getAvailabilityDomains(c); + ChoiceDescriptionData adChoices = new ChoiceDescriptionData<>( + ads.stream().map(ad -> new ChoiceDescription<>(ad.getName(), ad)).collect(Collectors.toList())); + AvailabilityDomain ad = TextIOUtils + .getParamChoice("Please chose the availability domain your instance is running in", adChoices); + log.info("Using AD " + ad.getName()); + + String instanceName = TextIOUtils.getString("What is the name of your instance ?", "demoinstance"); + ComputeProcessor cp = new ComputeProcessor(ap); + Instance i = cp.locateInstance(instanceName, c, ad); + if (i == null) { + log.info("Unable to locate an existing instance called " + instanceName + " in AD " + ad.getName() + + " in Compartment " + c.getName()); + } + + List vnicAttachments = cp.getInstanceVnicAttachements(i).stream().filter( + vnicAttachment -> vnicAttachment.getLifecycleState().equals(VnicAttachment.LifecycleState.Attached)) + .toList(); + List subNetOcids = vnicAttachments.stream().map(vnicAttachment -> vnicAttachment.getSubnetId()) + .distinct().toList(); + List vcnOcids = vnicAttachments.stream().map(vnicAttachment -> vnicAttachment.getSubnetId()).distinct() + .toList(); + + log.info("Instance is connected to subnets " + subNetOcids); + log.info("Instance is connected to vcns " + vcnOcids); + + boolean ableToDoDeletion = true; + String subnetOCIDToDelete = null; + if (subNetOcids.size() == 0) { + log.warn("There are no subnets, cannot actually delete anything, was instance " + instanceName + + " setup under this script ?"); + } else if (subNetOcids.size() == 1) { + subnetOCIDToDelete = subNetOcids.get(0); + log.info("Single subnet located"); + } else { + log.warn( + "There are multiple subnets, cannot actually delete anything, will retrieve details based on the first subnet, was instance " + + instanceName + " setup under this script ?"); + subnetOCIDToDelete = subNetOcids.get(0); + ableToDoDeletion = false; + } + String vcnOcidToDelete = null; + if (vcnOcids.size() == 0) { + log.warn("There are no vcns, cannot actually delete anything, was instance " + instanceName + + " setup under this script ?"); + } else if (vcnOcids.size() == 1) { + vcnOcidToDelete = vcnOcids.get(0); + log.info("Single vcn located"); + } else { + log.warn( + "There are multiple vcns, cannot actually delete anything, will retrieve details based on the first vcn, was instance " + + instanceName + " setup under this script?"); + vcnOcidToDelete = vcnOcids.get(0); + ableToDoDeletion = false; + } + + VCNProcessor vp = new VCNProcessor(ap); + List gateways = vp.listInternetGateways(c.getId(), vcnOcidToDelete); + + } +} diff --git a/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/storage/ObjectStorageInteract.java b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/storage/ObjectStorageInteract.java new file mode 100644 index 0000000..32ec2fe --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/storage/ObjectStorageInteract.java @@ -0,0 +1,186 @@ +/*Copyright (c) 2023 Oracle and/or its affiliates. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software (each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at +a minimum a reference to the UPL must 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. + */ +package com.oracle.timg.demo.examples.storage; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Collection; +import java.util.Comparator; + +import com.oracle.bmc.identity.model.Compartment; +import com.oracle.timg.oci.authentication.AuthenticationProcessor; +import com.oracle.timg.oci.identity.IdentityProcessor; +import com.oracle.timg.oci.objectstorage.ObjectStorageProcessor; + +import lombok.extern.slf4j.Slf4j; +import timgutilities.textio.TextIOUtils; + +@Slf4j +public class ObjectStorageInteract { + public final static String CONFIG_FILE_SECTION = "DEFAULT"; + public final static String MY_COMPARTMENT = "/domain-specialists/tim.graves"; + public final static String DEFAULT_BUCKET_NAME = "testbucket"; + public final static String DOWNLOADED_SUFFIX = "downloaded"; + + public static void main(String[] args) throws IllegalArgumentException, Exception { + String chosenConfigSection = TextIOUtils.getString("Chose the section in the config file", CONFIG_FILE_SECTION); + AuthenticationProcessor auth = new AuthenticationProcessor(chosenConfigSection); + IdentityProcessor identity = new IdentityProcessor(auth); + ObjectStorageProcessor objectStorage = new ObjectStorageProcessor(auth); + String compartmentToUse = TextIOUtils.getString("Enter the compartment path to use as the parent", + MY_COMPARTMENT); + Compartment compartment = identity.locateCompartmentByPath(compartmentToUse); + if (compartment == null) { + log.info("Can't locate compatment " + compartmentToUse); + System.exit(0); + } else { + log.info("Located compatment " + compartmentToUse + "it has ocid " + compartment.getId()); + } + String s3Compatibility = objectStorage.getS3CompatibilityCompartmentOCID(); + log.info("S3 compatibility compatment OCID is " + s3Compatibility); + // get the buckets list + Collection bucketNames = objectStorage.listBucketNamesInCompartment(compartment); + log.info("Located buckets " + bucketNames); + String bucketName = TextIOUtils.getString("Please chose the bucket name to use", DEFAULT_BUCKET_NAME); + if (objectStorage.bucketExists(bucketName)) { + log.info("Bucket named " + bucketName + " already exists"); + } else { + log.info("Bucket named " + bucketName + " does not exist, creating it"); + objectStorage.createBucketInCompartment(bucketName, compartment); + } + if (TextIOUtils.getYN("Do you want to test transfers ?", false)) { + String prefixRemote = TextIOUtils.getString("Please enter the remote prefix to use", "/Users/Tim"); + String prefixLocal = TextIOUtils.getDirectory("Please enter the local prefix to start from", + "/users/tg13456"); + String localFileName = TextIOUtils.getFileUnder( + "please enter the sample file to upload within " + prefixLocal, prefixLocal, + "Desktop/manifest-k8s-core.json"); + String localFullPathName = prefixLocal + "/" + localFileName; + if (TextIOUtils.getYN("Do you want to do a test upload ?", false)) { + log.info("Starting upload"); + objectStorage.uploadFile(bucketName, prefixRemote, localFileName, new File(localFullPathName)); + log.info("Completed upload"); + } + if (TextIOUtils.getYN("Do you want to do a test download ? (this will add " + DOWNLOADED_SUFFIX + + " to the file name you set) ", false)) { + log.info("Starting download"); + objectStorage.downloadFile(bucketName, prefixRemote, localFileName, + new File(localFullPathName + DOWNLOADED_SUFFIX)); + log.info("Completed download"); + } + if (TextIOUtils.getYN("Do you want to delete the object you just uploaded ?", false)) { + log.info("Starting delete"); + objectStorage.deleteObject(bucketName, prefixRemote, localFileName); + log.info("Completed delete"); + } + } + if (TextIOUtils.getYN("Do you want to try a directory transfers ?", false)) { + String prefixRemote = TextIOUtils.getString("Please enter the remote prefix to use", "/Users/Tim"); + String dirPrefixRemote = TextIOUtils.getString( + "Please enter the remote prefix to use for the directory upload", "/Users/Tim/directory"); + String dirPrefixLocal = TextIOUtils.getDirectory("Please enter the local prefix to start from", + "/users/tg13456"); + if (TextIOUtils.getYN("Do you want to try a directory upload ?", false)) { + String localName = TextIOUtils + .getString("please enter the sample directory to upload from within " + dirPrefixLocal); + String localPathName = dirPrefixLocal + "/" + localName; + + log.info("Starting Upload of " + localPathName + " with object storage prefix " + prefixRemote); + String res = objectStorage.uploadObject(bucketName, dirPrefixRemote, new File(localPathName)); + log.info("Upload Processed " + res); + } + File localParent = null; + if (TextIOUtils.getYN("Do you want to try a directory download ?", false)) { + String localName = TextIOUtils + .getDirectory( + "please enter the parent directory to download to - this will have a directory" + + DOWNLOADED_SUFFIX + " created within it to hold the download ", + dirPrefixLocal); + localName = localName + File.separator + DOWNLOADED_SUFFIX; + localParent = new File(localName); + if (!localParent.exists()) { + log.error(localName + " does not exist, attempting to create it"); + localParent.mkdirs(); + } + if (!localParent.isDirectory()) { + log.error(localName + " is not a directory, can't retrive a directory to it"); + } else { + log.info(" starting download of objects under prefix " + dirPrefixRemote + " to local directory of " + + localParent.getPath()); + objectStorage.downloadObject(bucketName, dirPrefixRemote, localParent); + } + } + if (TextIOUtils.getYN( + "Do you want to delete the object storage tree you just uploaded ? (this will not delete any locally downloaded versions) ", + false)) { + log.info("Starting delete"); + objectStorage.deleteObjectsInBucket(bucketName, dirPrefixRemote); + log.info("Completed delete"); + } + if ((localParent != null) && TextIOUtils.getYN( + "Do you want to delete the local directory you downloaded (" + localParent.getPath() + " ?", + false)) { + Files.walk(localParent.toPath()) // Traverse the file tree in depth-first order + .sorted(Comparator.reverseOrder()).forEach(path -> { + try { + System.out.println("Deleting: " + path); + Files.delete(path); // delete each file or directory + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + } + if (TextIOUtils.getYN("Do you want to check the prefixes ?", false)) { + String prefixRemote = TextIOUtils.getString("Please enter the remote prefix to use", "/Users/Tim"); + log.info("Retrieving objects within prefix"); + Collection objectsWithinPrefix = objectStorage.listObjectNamesInBucket(bucketName, prefixRemote); + log.info("Found " + objectsWithinPrefix.size() + " objects with prefoix " + prefixRemote + " they are named" + + objectsWithinPrefix); + log.info("Retrieved non split out prefixes from root " + + objectStorage.listPrefixesInBucket(bucketName, null, false)); + log.info("Retrieved split out from root prefixes " + + objectStorage.listPrefixesInBucket(bucketName, null, true)); + log.info("Retrieved non split out prefixes from prefix " + prefixRemote + " are " + + objectStorage.listPrefixesInBucket(bucketName, prefixRemote, false)); + log.info("Retrieved split out from prefixes from prefix " + prefixRemote + " are " + + objectStorage.listPrefixesInBucket(bucketName, prefixRemote, true)); + } + } + +} diff --git a/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/streams/ConnectTest.java b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/streams/ConnectTest.java new file mode 100644 index 0000000..909d24e --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/streams/ConnectTest.java @@ -0,0 +1,120 @@ +/*Copyright (c) 2023 Oracle and/or its affiliates. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software (each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at +a minimum a reference to the UPL must 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. + */ +package com.oracle.timg.demo.examples.streams; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import org.json.JSONObject; + +import com.oracle.bmc.auth.AuthenticationDetailsProvider; +import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; +import com.oracle.bmc.streaming.StreamClient; +import com.oracle.bmc.streaming.model.PutMessagesDetails; +import com.oracle.bmc.streaming.model.PutMessagesDetails.Builder; +import com.oracle.bmc.streaming.model.PutMessagesDetailsEntry; +import com.oracle.bmc.streaming.requests.PutMessagesRequest; +import com.oracle.bmc.streaming.responses.PutMessagesResponse; + +public class ConnectTest { + // public final static String STREAM_NAME = + // "ocid1.stream.oc1.phx.aaaaaaaaztwq3ocpjbu37zuaborcaeth2aw7ufcwrhlze2nzrrkwpw2nlpja"; + public final static String STREAM_NAME = "TimG"; + + public static void main(String[] args) { + + String messageKey = "timeStream"; + // build some JSON to do stuff with + JSONObject jsonObject = new JSONObject(); + // have the ID be based on the clock. not briliant but for now given we're only + // doing one message per invocation it's going to be pretty unique. + jsonObject.put("id", System.currentTimeMillis()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss.SSSS"); + jsonObject.put("timestamp", sdf.format(new Date())); + jsonObject.put("message", "Hello World!"); + String messageValue = jsonObject.toString(4); + // create an authentication provider, use the default file location + // $HOME/.oci/config and specify I wand to use the DEFAULT config. + AuthenticationDetailsProvider provider; + try { + provider = new ConfigFileAuthenticationDetailsProvider("API_USER"); + } catch (IOException e) { + e.printStackTrace(); + return; + } + StreamClient streamClient = StreamClient.builder().build(provider); + // Build the message details, for now this is broken into segments to make it + // easier + // the builder is independent of the actual stream + Builder builder = PutMessagesDetails.builder(); + // the builder can operate on many messages at a time, but we only have one + PutMessagesDetailsEntry message; + try { + message = PutMessagesDetailsEntry.builder().key(messageKey.getBytes("UTF-8")) + .value(messageValue.getBytes("UTF-8")).build(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return; + } + // messages are added in a list + List messagesList = Arrays.asList(message); + // build the mesages structure + PutMessagesDetails putMessagesDetails = builder.messages(messagesList).build(); + // now need to create a request to send the messages + PutMessagesRequest putMessagesRequest = PutMessagesRequest.builder() + .streamId("ocid1.stream.oc1.phx.aaaaaaaaztwq3ocpjbu37zuaborcaeth2aw7ufcwrhlze2nzrrkwpw2nlpja") + .putMessagesDetails(putMessagesDetails).build(); + // Finally get the client to send the request + System.out.println("Sending message " + putMessagesRequest); + PutMessagesResponse messagesResponse = streamClient.putMessages(putMessagesRequest); + System.out.println("Got response " + messagesResponse + .toString());/* + * // let's find out what happened String responseId = + * messagesResponse.getOpcRequestId() ; PutMessagesResult putMessagesResult = + * messagesResponse.getPutMessagesResult() ; int failuresCount = + * putMessagesResult.getFailures() ; List + * messagesResults = putMessagesResult.getEntries() ; + * System.out.println("Send message "+); + */ + + } + +} diff --git a/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/streams/ListStreams.java b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/streams/ListStreams.java new file mode 100644 index 0000000..116625c --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/streams/ListStreams.java @@ -0,0 +1,69 @@ +/*Copyright (c) 2023 Oracle and/or its affiliates. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software (each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at +a minimum a reference to the UPL must 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. + */ +package com.oracle.timg.demo.examples.streams; + +import java.io.IOException; +import java.util.stream.Collectors; + +import com.oracle.bmc.auth.AuthenticationDetailsProvider; +import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; +import com.oracle.bmc.streaming.StreamAdminClient; +import com.oracle.bmc.streaming.requests.ListStreamsRequest; +import com.oracle.bmc.streaming.responses.ListStreamsResponse; + +public class ListStreams { + + public static void main(String[] args) { + // create an authentication provider, use the default file location + // $HOME/.oci/config and specify I wand to use the DEFAULT config. + AuthenticationDetailsProvider provider; + try { + provider = new ConfigFileAuthenticationDetailsProvider("API_USER"); + } catch (IOException e) { + e.printStackTrace(); + return; + } + StreamAdminClient streamAdminClient = StreamAdminClient.builder().build(provider); + ListStreamsRequest request = ListStreamsRequest.builder() + .compartmentId("ocid1.compartment.oc1..aaaaaaaavxkbsxpb3j7iml4rxe4hbnjzagu6xmcjnbmctg32ptqvldmhx6yq") + .build(); + ListStreamsResponse listResponse = streamAdminClient.listStreams(request); + String streams = listResponse.getItems().stream().map(resp -> resp.toString()).collect(Collectors.joining(",")); + System.out.println("Resp = " + streams); + } + +} diff --git a/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/streams/StreamsExample.java b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/streams/StreamsExample.java new file mode 100644 index 0000000..7d044be --- /dev/null +++ b/oci-java-sdk-simple-wrappers-testing/src/main/java/com/oracle/timg/demo/examples/streams/StreamsExample.java @@ -0,0 +1,277 @@ +/*Copyright (c) 2023 Oracle and/or its affiliates. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any +person obtaining a copy of this software, associated documentation and/or data +(collectively the "Software"), free of charge and under any and all copyright +rights in the Software, and any and all patent rights owned or freely +licensable by each licensor hereunder covering either (i) the unmodified +Software as contributed to or provided by such licensor, or (ii) the Larger +Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if +one is included with the Software (each a "Larger Work" to which the Software +is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create +derivative works of, display, perform, and distribute the Software and make, +use, sell, offer for sale, import, export, have made, and have sold the +Software and the Larger Work(s), and to sublicense the foregoing rights on +either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at +a minimum a reference to the UPL must 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. + */ +package com.oracle.timg.demo.examples.streams; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import com.google.common.util.concurrent.Uninterruptibles; +import com.oracle.bmc.auth.AuthenticationDetailsProvider; +import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider; +import com.oracle.bmc.streaming.StreamAdminClient; +import com.oracle.bmc.streaming.StreamClient; +import com.oracle.bmc.streaming.model.CreateCursorDetails; +import com.oracle.bmc.streaming.model.CreateCursorDetails.Type; +import com.oracle.bmc.streaming.model.CreateGroupCursorDetails; +import com.oracle.bmc.streaming.model.CreateStreamDetails; +import com.oracle.bmc.streaming.model.Message; +import com.oracle.bmc.streaming.model.PutMessagesDetails; +import com.oracle.bmc.streaming.model.PutMessagesDetailsEntry; +import com.oracle.bmc.streaming.model.PutMessagesResultEntry; +import com.oracle.bmc.streaming.model.Stream; +import com.oracle.bmc.streaming.model.Stream.LifecycleState; +import com.oracle.bmc.streaming.requests.CreateCursorRequest; +import com.oracle.bmc.streaming.requests.CreateGroupCursorRequest; +import com.oracle.bmc.streaming.requests.CreateStreamRequest; +import com.oracle.bmc.streaming.requests.DeleteStreamRequest; +import com.oracle.bmc.streaming.requests.GetMessagesRequest; +import com.oracle.bmc.streaming.requests.GetStreamRequest; +import com.oracle.bmc.streaming.requests.ListStreamsRequest; +import com.oracle.bmc.streaming.requests.PutMessagesRequest; +import com.oracle.bmc.streaming.responses.CreateCursorResponse; +import com.oracle.bmc.streaming.responses.CreateGroupCursorResponse; +import com.oracle.bmc.streaming.responses.CreateStreamResponse; +import com.oracle.bmc.streaming.responses.GetMessagesResponse; +import com.oracle.bmc.streaming.responses.GetStreamResponse; +import com.oracle.bmc.streaming.responses.ListStreamsResponse; +import com.oracle.bmc.streaming.responses.PutMessagesResponse; + +/** + * This class provides an example of basic streaming usage. - List streams - Get + * a stream - Create a stream - Delete a stream - Publish to a stream - Consume + * from a stream partition, using a cursor - Consume from a stream, using a + * group cursor + */ +public class StreamsExample { + + public static void main(String[] args) throws Exception { + final String configurationFilePath = "~/.oci/config"; + final String profile = "DEFAULT"; + + final AuthenticationDetailsProvider provider = new ConfigFileAuthenticationDetailsProvider( + configurationFilePath, profile); + + // Create an admin-client for the phoenix region. + final StreamAdminClient adminClient = StreamAdminClient.builder().build(provider); + + final String compartmentId = "ocid1.compartment.oc1..aaaaaaaavxkbsxpb3j7iml4rxe4hbnjzagu6xmcjnbmctg32ptqvldmhx6yq"; + final String exampleStreamName = "sdk-example-stream"; + final int partitions = 1; + + // We want to be good samaritan, so we'll reuse a stream if its already created. + // This will utilize ListStreams() to determine if a stream exists and return + // it, or create a new one. + Stream stream = getOrCreateStream(adminClient, compartmentId, exampleStreamName, partitions); + + // Streams are assigned a specific endpoint url based on where they are + // provisioned. + // Create a stream client using the provided message endpoint. + StreamClient streamClient = StreamClient.builder().build(provider); + streamClient.setEndpoint(stream.getMessagesEndpoint()); + + String streamId = stream.getId(); + + // publish some messages to the stream + publishExampleMessages(streamClient, streamId); + + // give the streaming service a second to propagate messages + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + + // Use a cursor for getting messages; each getMessages call will return a + // next-cursor for iteration. + // There are a couple kinds of cursors. + + // A cursor can be created at a given partition/offset. + // This gives explicit offset management control to the consumer. + System.out.println("Starting a simple message loop with a partition cursor"); + String partitionCursor = getCursorByPartition(streamClient, streamId, "0"); + simpleMessageLoop(streamClient, streamId, partitionCursor); + + // A cursor can be created as part of a consumer group. + // Committed offsets are managed for the group, and partitions + // are dynamically balanced amongst consumers in the group. + System.out.println("Starting a simple message loop with a group cursor"); + String groupCursor = getCursorByGroup(streamClient, streamId, "exampleGroup", "exampleInstance-1"); + simpleMessageLoop(streamClient, streamId, groupCursor); + + // Cleanup; remember to delete streams which are not in use. + deleteStream(adminClient, streamId); + + // Stream deletion is an asynchronous operation, give it some time to complete. + + GetStreamRequest streamRequest = GetStreamRequest.builder().streamId(streamId).build(); + adminClient.getWaiters().forStream(streamRequest, LifecycleState.Deleted).execute(); + } + + private static void deleteStream(StreamAdminClient adminClient, String streamId) { + System.out.println("Deleting stream " + streamId); + adminClient.deleteStream(DeleteStreamRequest.builder().streamId(streamId).build()); + } + + private static String getCursorByGroup(StreamClient streamClient, String streamId, String groupName, + String instanceName) { + System.out.println(String.format("Creating a cursor for group %s, instance %s.", groupName, instanceName)); + + CreateGroupCursorDetails cursorDetails = CreateGroupCursorDetails.builder().groupName(groupName) + .instanceName(instanceName).type(CreateGroupCursorDetails.Type.TrimHorizon).commitOnGet(true).build(); + + CreateGroupCursorRequest createCursorRequest = CreateGroupCursorRequest.builder().streamId(streamId) + .createGroupCursorDetails(cursorDetails).build(); + + CreateGroupCursorResponse groupCursorResponse = streamClient.createGroupCursor(createCursorRequest); + return groupCursorResponse.getCursor().getValue(); + } + + private static String getCursorByPartition(StreamClient streamClient, String streamId, String partition) { + System.out.println(String.format("Creating a cursor for partition %s.", partition)); + + CreateCursorDetails cursorDetails = CreateCursorDetails.builder().partition(partition).type(Type.TrimHorizon) + .build(); + + CreateCursorRequest createCursorRequest = CreateCursorRequest.builder().streamId(streamId) + .createCursorDetails(cursorDetails).build(); + + CreateCursorResponse cursorResponse = streamClient.createCursor(createCursorRequest); + return cursorResponse.getCursor().getValue(); + } + + private static Stream getStream(StreamAdminClient adminClient, String streamId) { + GetStreamResponse getResponse = adminClient.getStream(GetStreamRequest.builder().streamId(streamId).build()); + return getResponse.getStream(); + } + + private static Stream getOrCreateStream(StreamAdminClient adminClient, String compartmentId, String streamName, + int partitions) throws Exception { + + ListStreamsRequest listRequest = ListStreamsRequest.builder().compartmentId(compartmentId) + .lifecycleState(LifecycleState.Active).name(streamName).build(); + + ListStreamsResponse listResponse = adminClient.listStreams(listRequest); + + if (!listResponse.getItems().isEmpty()) { + // if we find an active stream with the correct name, we'll use it. + System.out.println(String.format("An active stream named %s was found.", streamName)); + + String streamId = listResponse.getItems().get(0).getId(); + return getStream(adminClient, streamId); + } + + System.out.println(String.format("No active stream named %s was found; creating it now.", streamName)); + Stream createdStream = createStream(adminClient, compartmentId, streamName, partitions); + + // GetStream provides details about a specific stream. + // Since stream creation is asynchronous; we need to wait for the stream to + // become active. + GetStreamRequest streamRequest = GetStreamRequest.builder().streamId(createdStream.getId()).build(); + Stream activeStream = adminClient.getWaiters().forStream(streamRequest, LifecycleState.Active).execute() + .getStream(); + + // Give a little time for the stream to be ready. + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + return activeStream; + } + + private static Stream createStream(StreamAdminClient adminClient, String compartmentId, String streamName, + int partitions) { + System.out.println(String.format("Creating stream %s with %s partitions", streamName, partitions)); + + CreateStreamDetails streamDetails = CreateStreamDetails.builder().compartmentId(compartmentId).name(streamName) + .partitions(partitions).build(); + + CreateStreamRequest createStreamRequest = CreateStreamRequest.builder().createStreamDetails(streamDetails) + .build(); + + CreateStreamResponse createResponse = adminClient.createStream(createStreamRequest); + return createResponse.getStream(); + } + + private static void publishExampleMessages(StreamClient streamClient, String streamId) { + // build up a putRequest and publish some messages to the stream + List messages = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + messages.add(PutMessagesDetailsEntry.builder().key(String.format("messageKey-%s", i).getBytes(UTF_8)) + .value(String.format("messageValue-%s", i).getBytes(UTF_8)).build()); + } + + System.out.println(String.format("Publishing %s messages to stream %s.", messages.size(), streamId)); + PutMessagesDetails messagesDetails = PutMessagesDetails.builder().messages(messages).build(); + + PutMessagesRequest putRequest = PutMessagesRequest.builder().streamId(streamId) + .putMessagesDetails(messagesDetails).build(); + + PutMessagesResponse putResponse = streamClient.putMessages(putRequest); + + // the putResponse can contain some useful metadata for handling failures + for (PutMessagesResultEntry entry : putResponse.getPutMessagesResult().getEntries()) { + if (entry.getError().trim().length() == 0) { + System.out.println(String.format("Error(%s): %s", entry.getError(), entry.getErrorMessage())); + } else { + System.out.println(String.format("Published message to partition %s, offset %s.", entry.getPartition(), + entry.getOffset())); + } + } + } + + private static void simpleMessageLoop(StreamClient streamClient, String streamId, String initialCursor) { + String cursor = initialCursor; + for (int i = 0; i < 10; i++) { + + GetMessagesRequest getRequest = GetMessagesRequest.builder().streamId(streamId).cursor(cursor).limit(10) + .build(); + + GetMessagesResponse getResponse = streamClient.getMessages(getRequest); + + // process the messages + System.out.println(String.format("Read %s messages.", getResponse.getItems().size())); + for (Message message : getResponse.getItems()) { + System.out.println(String.format("%s: %s", new String(message.getKey(), UTF_8), + new String(message.getValue(), UTF_8))); + } + + // getMessages is a throttled method; clients should retrieve sufficiently large + // message + // batches, as to avoid too many http requests. + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + + // use the next-cursor for iteration + cursor = getResponse.getOpcNextCursor(); + } + } +} \ No newline at end of file diff --git a/oci-java-sdk-simple-wrappers/.factorypath b/oci-java-sdk-simple-wrappers/.factorypath new file mode 100644 index 0000000..5f841c5 --- /dev/null +++ b/oci-java-sdk-simple-wrappers/.factorypath @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/oci-java-sdk-simple-wrappers/.settings/org.eclipse.jdt.apt.core.prefs b/oci-java-sdk-simple-wrappers/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..dfa4f3a --- /dev/null +++ b/oci-java-sdk-simple-wrappers/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=true +org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations +org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations diff --git a/oci-java-sdk-simple-wrappers/pom.xml b/oci-java-sdk-simple-wrappers/pom.xml index 3a0e757..ea153f6 100644 --- a/oci-java-sdk-simple-wrappers/pom.xml +++ b/oci-java-sdk-simple-wrappers/pom.xml @@ -34,18 +34,23 @@ 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. --> - + 4.0.0 com.oracle.timg.demo oci-java-sdk-simple-wrappers ocicore 1.0.1 + jar + 21 + 21 UTF-8 - 3.17.0 - 1.18.28 + 3.77.0 + 1.18.42 2.0.7 - 17 + 21 ${maven.compiler.source} @@ -64,7 +69,8 @@ SOFTWARE. --> com.oracle.oci.sdk oci-java-sdk-core - + com.oracle.oci.sdk oci-java-sdk-common-httpclient-jersey3 @@ -81,6 +87,14 @@ SOFTWARE. --> com.oracle.oci.sdk oci-java-sdk-identity + + com.oracle.oci.sdk + oci-java-sdk-vault + + + com.oracle.oci.sdk + oci-java-sdk-iot + org.projectlombok @@ -88,7 +102,8 @@ SOFTWARE. --> ${version.lombok} compile -